﻿using System.Windows.Forms;
using Infragistics.Controls.Schedules;
using Infragistics.Windows.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Common.Helper;
using VNet.VisiSuite.Controls;
using VNet.VisiSuite.ExcelReader;
using VNet.VisiSuite.ExcelReader.ExcelReaderFactory;
using VNet.VisiSuite.ExcelReader.Models;
using VNet.VisiSuite.Service.Contact.Message.Base;
using VNet.VisiSuite.Service.Contact.Message.Item;
using VNet.VisiSuite.VisiAdmin.Common.Helpers;
using VNet.VisiSuite.VisiAdmin.Models;
using VNet.VisiSuite.VisiAdmin.Properties;
using VNet.VisiSuite.VisiAdmin.Providers;
using VNet.VisiSuite.VisiAdmin.Views;
using VNet.VisiSuite.Common;
using VNet.VisiSuite.Common.Security;
using VNet.VisiSuite.Service.Proxy;
using MessageBox = System.Windows.MessageBox;

namespace VNet.VisiSuite.VisiAdmin.ViewModels
{
    public class AreaDetailsViewModel : BaseViewModel
    {
        #region Fields
        private AreaModel _currentAreaModel;
        private TabItemEx _selectedTabItem;
        private string _contentPaneHeader;
        private object _selectedObject;
        private object _pendingObject;
        private VNetMenuItem _importProductionPlanIcon;

        private ObservableCollection<AreaShiftModel> _areaShifts;
        private AreaShiftModel _cloneSelectedAreaShift;

        private ObservableCollection<LaunchApplicationModel> _launchApplications;
        private LaunchApplicationModel _cloneSelectedLaunchApplication;

        private ObservableCollection<ReasonCodeModel> _reasonCodes;
        private ObservableCollection<RollupDefinitionModel> _rollupDefinitionsSourceList;
        private ObservableCollection<ReasonCodeModel> _reasonCodesSourceList;
        private ObservableCollection<ReasonCodeModel> _reasonCodesSourceComboList;
        private ReasonCodeModel _cloneSelectedReasonCode;

        private ObservableCollection<RollupDefinitionModel> _rollupDefinitions;
        private RollupDefinitionModel _cloneSelectedRollupDefinition;

        private ObservableCollection<AlarmSettingModel> _alarmSettings;
        private AlarmSettingModel _cloneSelectedAlarmSetting;

        private ObservableCollection<ReasonCodeModel> _scrapReasonCodes;
        private ObservableCollection<ReasonCodeModel> _scrapReasonCodesSourceList;
        private ReasonCodeModel _cloneSelectedScrapReasonCode;


        private ObservableCollection<ScheduleModel> _schedules;
        private ObservableCollection<ScheduleModel> _scheduleSourceList;
        private ScheduleModel _cloneSelectedSchedule;

        private ObservableCollection<ScheduleRepeatModel> _scheduleRepeatList;


        private const string _shiftPropertyHeader = "Shift Properties";
        private const string _applicationPropertyHeader = "Launch Application Properties";
        private const string _reasonCodePropertyHeader = "Reason Code Properties";
        private const string _rollupDefPropertyHeader = "Rollup Definition Properties";
        private const string _scrapReasonCodePropertyHeader = "Scrap Reason Code Properties";
        private const string _productionPlanPropertyHeader = "Production Plan Properties";
        private const string _alarmSettingPropertyHeader = "Alarm Setting Properties";
        private const string _schedulePropertyHeader = "Scherdule Properties";
        private VNetMenuItem _addNewIcon;
        private VNetMenuItem _moveUpIcon;
        private VNetMenuItem _moveDownIcon;
        private ObservableCollection<ProductionPlanModel> _productionPlans;
        private ObservableCollection<ProductionPlanModel> _filteredProductionPlans;
        private ProductionPlanModel _cloneSelectedProductionPlan;
        private ProductionPlanReferenceModel _productionPlanReference;

        private ObservableCollection<Resource> _scheduleResources;
        private ObservableCollection<ResourceCalendar> _scheduleResourceCalendars;
        private ObservableCollection<Appointment> _scheduleDowntimes;

        private DateTime _startDate = DateTime.Today;
        private DateTime _endDate = DateTime.Today;
        private Visibility _parent_reason_tree_visibility = Visibility.Collapsed;
        private string _parent_reason_tree_button_content = "Show";
        private Visibility _link_reason_tree_visibility = Visibility.Collapsed;
        private string _link_reason_tree_button_content = "Show";
        private string _parent_scrap_reason_tree_button_content = "Show";
        private Visibility _parent_scrap_reason_tree_visibility = Visibility.Collapsed;
        private Visibility _link_scrap_reason_tree_visibility = Visibility.Collapsed;
        private string _link_scrap_reason_tree_button_content = "Show";

        #endregion

        public AreaDetailsViewModel()
        {

            var request = new GetDataRequest
            {
                Identity = UserTransportToken.UserIdentity,
                Id = 1,
            };
            var client = new VNetVisiSuiteContractClient();
            var obj = client.GetScheduledRepeat(request);

            

            TopLeftButtonIcons = new ObservableCollection<VNetMenuItem> { new VNetMenuItem(null, "Return to previous screen", CommonConstants.VNetIcon.AppbarArrowLeft, VNetMenuItemType.WhiteBackgroundTheme, OnExit), };
            _addNewIcon = new VNetMenuItem(null, null, CommonConstants.VNetIcon.AppbarListAdd, VNetMenuItemType.WhiteBackgroundTheme, OnAddNewItemCallback);
            _moveUpIcon = new VNetMenuItem(null, "Move up", CommonConstants.VNetIcon.AppbarArrowUp, VNetMenuItemType.WhiteBackgroundTheme, OnMoveUpCallback) { IsEnabled = false, };
            _moveDownIcon = new VNetMenuItem(null, "Move down", CommonConstants.VNetIcon.AppbarArrowDown, VNetMenuItemType.WhiteBackgroundTheme, OnMoveDownCallback) { IsEnabled = false, };
            TopRightButtonIcons = new ObservableCollection<VNetMenuItem> { _moveUpIcon, _moveDownIcon, _addNewIcon };
            BottomMenuItems = new ObservableCollection<VNetMenuItem>();
            _importProductionPlanIcon = new VNetMenuItem("Import Production Plans", "Import Production Plans", CommonConstants.VNetIcon.AppbarOfficeExcel, VNetMenuItemType.BlackBackgroundTheme, ImportProductionPlanMenuClick);
            BottomMenuItems.Add(_importProductionPlanIcon);
            ShiftTabHeader = "Shifts";
            ApplicationTabHeader = "Applications";
            ReasonCodeTabHeader = "Downtime Reason Codes";
            RollupDefTabHeader = "Rollup Definitions";
            AlarmSettingTabHeader = "Alarm Settings";
            ScrapReasonCodeTabHeader = "Scrap Reason Codes";
            ProductionPlanTabHeader = "Production Plan";
            ScheduledDowntimeTabHeader = "Scheduled Downtime";

            SaveAreaShiftCommand = new RelayCommand(DoSaveAreaShift);
            CancelAreaShiftCommand = new RelayCommand(DoCancelAreaShift);
            DeleteAreaShiftCommand = new RelayCommand(DoDeleteAreaShift);

            SaveLaunchApplicationCommand = new RelayCommand(DoSaveLaunchApplication);
            CancelLaunchApplicationCommand = new RelayCommand(DoCancelLaunchApplication);
            DeleteLaunchApplicationCommand = new RelayCommand(DoDeleteLaunchApplication);

            SaveReasonCodeCommand = new RelayCommand(DoSaveReasonCode);
            CancelReasonCodeCommand = new RelayCommand(DoCancelReasonCode);
            DeleteReasonCodeCommand = new RelayCommand(DoDeleteReasonCode);

            SaveRollupDefCommand = new RelayCommand(DoSaveRollupDef);
            CancelRollupDefCommand = new RelayCommand(DoCancelRollupDef);
            DeleteRollupDefCommand = new RelayCommand(DoDeleteRollupDef);

            SaveScrapReasonCodeCommand = new RelayCommand(DoSaveScrapReasonCode);
            CancelScrapReasonCodeCommand = new RelayCommand(DoCancelScrapReasonCode);
            DeleteScrapReasonCodeCommand = new RelayCommand(DoDeleteScrapReasonCode);

            SaveProductionPlanCommand = new RelayCommand(DoSaveProductionPlanCommand);
            CancelProductionPlanCommand = new RelayCommand(DoCancelProductionPlanCommand);
            DeleteProductionPlanCommand = new RelayCommand(DoDeleteProductionPlanCommand);

            SaveAlarmSettingCommand = new RelayCommand(DoSaveAlarmSetting);
            CancelAlarmSettingCommand = new RelayCommand(DoCancelAlarmSetting);
            DeleteAlarmSettingCommand = new RelayCommand(DoDeleteAlarmSetting);

            ParentReasonTreeClickCommand = new RelayCommand(OnParentReasonCodeClick);
            LinkReasonTreeClickCommand = new RelayCommand(OnLinkReasonCodeClick);
            ParentScrapReasonTreeClickCommand = new RelayCommand(OnParentScrapReasonCodeClick);
            LinkScrapReasonTreeClickCommand = new RelayCommand(OnLinkScrapReasonCodeClick);

            SaveScheduleCommand = new RelayCommand(DoSaveSchedule);
            CancelScheduleCommand = new RelayCommand(DoCancelSchedule);
            DeleteScheduleCommand = new RelayCommand(DoDeleteSchedule);

        }

        #region Properties
        public string ShiftTabHeader { get; set; }
        public string ApplicationTabHeader { get; set; }
        public string ProductionPlanTabHeader { get; set; }
        public string ReasonCodeTabHeader { get; set; }
        public string RollupDefTabHeader { get; set; }
        public string AlarmSettingTabHeader { get; set; }
        public string ScrapReasonCodeTabHeader { get; set; }
        public string ScheduledDowntimeTabHeader { get; set; }

        public RelayCommand SaveAreaShiftCommand { get; set; }
        public RelayCommand CancelAreaShiftCommand { get; set; }
        public RelayCommand DeleteAreaShiftCommand { get; set; }

        public RelayCommand SaveLaunchApplicationCommand { get; set; }
        public RelayCommand CancelLaunchApplicationCommand { get; set; }
        public RelayCommand DeleteLaunchApplicationCommand { get; set; }

        public RelayCommand SaveReasonCodeCommand { get; set; }
        public RelayCommand CancelReasonCodeCommand { get; set; }
        public RelayCommand DeleteReasonCodeCommand { get; set; }

        public RelayCommand SaveRollupDefCommand { get; set; }
        public RelayCommand CancelRollupDefCommand { get; set; }
        public RelayCommand DeleteRollupDefCommand { get; set; }

        public RelayCommand SaveScrapReasonCodeCommand { get; set; }
        public RelayCommand CancelScrapReasonCodeCommand { get; set; }
        public RelayCommand DeleteScrapReasonCodeCommand { get; set; }

        public RelayCommand SaveProductionPlanCommand { get; set; }
        public RelayCommand CancelProductionPlanCommand { get; set; }
        public RelayCommand DeleteProductionPlanCommand { get; set; }

        public RelayCommand SaveAlarmSettingCommand { get; set; }
        public RelayCommand CancelAlarmSettingCommand { get; set; }
        public RelayCommand DeleteAlarmSettingCommand { get; set; }

        public RelayCommand ParentReasonTreeClickCommand { get; set; }
        public RelayCommand LinkReasonTreeClickCommand { get; set; }
        public RelayCommand ParentScrapReasonTreeClickCommand { get; set; }
        public RelayCommand LinkScrapReasonTreeClickCommand { get; set; }


        public RelayCommand SaveScheduleCommand { get; set; }
        public RelayCommand CancelScheduleCommand { get; set; }
        public RelayCommand DeleteScheduleCommand { get; set; }


        public string ParentScrapReasonTreeButtonContent
        {
            get { return _parent_scrap_reason_tree_button_content; }
            set
            {
                if (_parent_scrap_reason_tree_button_content == value)
                    return;
                _parent_scrap_reason_tree_button_content = value;
                OnPropertyChanged("ParentScrapReasonTreeButtonContent");

            }
        }

        public Visibility ParentScrapReasonTreeVisibility
        {
            get { return _parent_scrap_reason_tree_visibility; }
            set
            {
                if (_parent_scrap_reason_tree_visibility == value)
                    return;
                _parent_scrap_reason_tree_visibility = value;
                OnPropertyChanged("ParentScrapReasonTreeVisibility");
            }
        }

        public string LinkScrapReasonTreeButtonContent
        {
            get { return _link_scrap_reason_tree_button_content; }
            set
            {
                if (_link_scrap_reason_tree_button_content == value)
                    return;
                _link_scrap_reason_tree_button_content = value;
                OnPropertyChanged("LinkScrapReasonTreeButtonContent");
            }
        }

        public Visibility LinkScrapReasonTreeVisibility
        {
            get { return _link_scrap_reason_tree_visibility; }
            set
            {
                if (_link_scrap_reason_tree_visibility == value)
                    return;
                _link_scrap_reason_tree_visibility = value;
                OnPropertyChanged("LinkScrapReasonTreeVisibility");
            }
        }

        public string ParentReasonTreeButtonContent
        {
            get { return _parent_reason_tree_button_content; }
            set
            {
                if (_parent_reason_tree_button_content == value)
                    return;
                _parent_reason_tree_button_content = value;
                OnPropertyChanged("ParentReasonTreeButtonContent");
            }
        }

        public Visibility ParentReasonTreeVisibility
        {
            get { return _parent_reason_tree_visibility; }
            set
            {
                if (_parent_reason_tree_visibility == value)
                    return;
                _parent_reason_tree_visibility = value;
                OnPropertyChanged("ParentReasonTreeVisibility");
            }
        }

        public string LinkReasonTreeButtonContent
        {
            get { return _link_reason_tree_button_content; }
            set
            {
                if (_link_reason_tree_button_content == value)
                    return;
                _link_reason_tree_button_content = value;
                OnPropertyChanged("LinkReasonTreeButtonContent");
            }
        }

        public Visibility LinkReasonTreeVisibility
        {
            get { return _link_reason_tree_visibility; }
            set
            {
                if (_link_reason_tree_visibility == value)
                    return;
                _link_reason_tree_visibility = value;
                OnPropertyChanged("LinkReasonTreeVisibility");
            }
        }

        /// <summary>
        /// Using for lazy loading of tab control
        /// </summary>
        public TabItemEx SelectedTabItem
        {
            get { return _selectedTabItem; }
            set
            {
                _selectedTabItem = value;
                _addNewIcon.Tooltip = null;

                if (_selectedTabItem != null && _currentAreaModel != null)
                {
                    var header = _selectedTabItem.Header.ToString();
                    if (header == ShiftTabHeader)
                    {
                        _addNewIcon.Tooltip = "Add new Shift";

                        if (AreaShifts == null)
                        {
                            IsBusy = true;
                            DoAsync(AreaProvider.GetAreaShifts, GetAreaShiftsCompleted, _currentAreaModel.AreaId);
                        }
                    }
                    else if (header == ApplicationTabHeader && LaunchApplications == null)
                    {
                        _addNewIcon.Tooltip = "Add new Application";
                        if (LaunchApplications == null)
                        {
                            IsBusy = true;
                            DoAsync(AreaProvider.GetLaunchApplications, GetLaunchApplicationsCompleted, _currentAreaModel.AreaId);
                        }
                    }
                    else if (header == ReasonCodeTabHeader)
                    {
                        _addNewIcon.Tooltip = "Add new Reason Code";

                        if (ReasonCodes == null)
                        {
                            IsBusy = true;
                            DoAsync(AreaProvider.GetRollupDefinitionsAsSource, GetRollupDefinitionsAsSourceCompleted, _currentAreaModel.AreaId);
                        }
                    }
                    else if (header == RollupDefTabHeader)
                    {
                        _addNewIcon.Tooltip = "Add new Rollup Definition";

                        if (RollupDefinitions == null)
                        {
                            IsBusy = true;
                            DoAsync(AreaProvider.GetRollupDefinitions, GetRollupDefinitionsCompleted, _currentAreaModel.AreaId);
                        }
                    }
                    else if (header == AlarmSettingTabHeader)
                    {
                        _addNewIcon.Tooltip = "Add new Alarm Setting";

                        if (AlarmSettings == null)
                        {
                            //IsBusy = true;
                            DoAsync(AreaProvider.GetAlarmSettings, GetAlarmSettingsCompleted, _currentAreaModel.AreaId);
                        }
                    }
                    else if (header == ScrapReasonCodeTabHeader)
                    {
                        _addNewIcon.Tooltip = "Add new Scrap Reason Code";

                        if (ScrapReasonCodes == null)
                        {
                            IsBusy = true;
                            DoAsync(AreaProvider.GetScrapReasonCodes, GetScrapReasonCodesCompleted, _currentAreaModel.AreaId);
                        }
                    }
                    else if (header == ProductionPlanTabHeader)
                    {
                        _addNewIcon.Tooltip = "Add new Production Plan";

                        if (ProductionPlans == null)
                        {
                            IsBusy = true;
                            DoAsync(ProductionPlanProviders.GetProductionPlanReference, GetProductionPlanReferenceCompleted, _currentAreaModel.AreaId);
                        }
                    }
                    else if (header == ScheduledDowntimeTabHeader)
                    {
                        _addNewIcon.Tooltip = "Add new Scheduled Downtime";

                        if (ScheduledDowntimes == null)
                        {
                            IsBusy = true;
                            DoAsync(AreaProvider.GetScheduledDowntimes, GetScheduledDowntimeCompleted, _currentAreaModel.AreaId);

                            //Get ReasonCode level 1 to combobox
                            var request = new GetDataRequest
                            {
                                Identity = UserTransportToken.UserIdentity,
                                Id = _currentAreaModel.AreaId,
                            };
                            var client = new VNetVisiSuiteContractClient();
                            var obj = client.GetReasonCodes(request).Data.Where(t => t.Level == 1);
                            var listCombo = new ObservableCollection<ReasonCodeModel>();
                            foreach (var item in obj)
                            {
                                listCombo.Add(new ReasonCodeModel
                                {
                                    ReasonCodeId = item.ReasonCodeId,
                                    Description = item.Description,
                                });
                            }
                            ReasonCodesSourceComboList = listCombo;
                        }
                    }
                }
                // why is this here? (abutler) OnPropertyChanged("SelectedTabItem");
            }
        }

        public string ContentPaneHeader
        {
            get { return _contentPaneHeader; }
            set
            {
                if (_contentPaneHeader == value) return;
                _contentPaneHeader = value;
                OnPropertyChanged("ContentPaneHeader");
            }
        }

        public object SelectedObject
        {
            get { return _selectedObject; }
            set
            {
                if (_selectedObject != null)
                {
                    var currentType = _selectedObject.GetType();
                    if (currentType == typeof(AreaShiftModel) && IsAreaShiftPendingChange(value)
                        || currentType == typeof(LaunchApplicationModel) && IsApplicationPendingChange(value)
                        || ((currentType == typeof(ReasonCodeModel) && !((ReasonCodeModel)_selectedObject).Scrap && IsReasonCodePendingChange(value))
                        || (currentType == typeof(ReasonCodeModel) && ((ReasonCodeModel)_selectedObject).Scrap && IsScrapReasonCodePendingChange(value)))
                        || currentType == typeof(RollupDefinitionModel) && IsRollupDefPendingChange(value)
                        || currentType == typeof(ProductionPlanModel) && IsProductionPlanPendingChange(value)
                        || currentType == typeof(AlarmSettingModel) && IsAlarmSettingPendingChange(value)
                        || currentType == typeof(ScheduleModel) && IsScheduledDowntimePendingChange(value)
                        )
                    {
                        return;
                    }
                }

                _selectedObject = null;
                OnPropertyChanged("SelectedObject");

                ContentPaneHeader = _shiftPropertyHeader;
                CloneSelectedAreaShift = null;
                CloneSelectedLaunchApplication = null;
                CloneSelectedReasonCode = null;
                CloneSelectedScrapReasonCode = null;
                CloneSelectedRollupDefinition = null;
                CloneSelectedProductionPlan = null;
                CloneSelectedAlarmSetting = null;
                CloneSelectedSchedule = null;

                if (value != null)
                {
                    _moveDownIcon.IsEnabled = _moveUpIcon.IsEnabled = false;
                    _pendingObject = null;
                    var valueType = value.GetType();
                    if (valueType == typeof(AreaShiftModel))
                    {
                        CloneAndBindingAreaShift((AreaShiftModel)value);
                    }
                    else if (valueType == typeof(LaunchApplicationModel))
                    {
                        _moveDownIcon.IsEnabled = _moveUpIcon.IsEnabled = true;
                        ContentPaneHeader = _applicationPropertyHeader;
                        CloneAndBindingLaunchApplication((LaunchApplicationModel)value);
                    }
                    else if (valueType == typeof(ReasonCodeModel))
                    {
                        var reasonCode = (ReasonCodeModel)value;
                        if (!reasonCode.Scrap)
                        {
                            ContentPaneHeader = _reasonCodePropertyHeader;
                            CloneAndBindingReasonCode((ReasonCodeModel)value);
                        }
                        else
                        {
                            ContentPaneHeader = _scrapReasonCodePropertyHeader;
                            CloneAndBindingScrapReasonCode((ReasonCodeModel)value);
                        }
                    }
                    else if (valueType == typeof(RollupDefinitionModel))
                    {
                        _moveDownIcon.IsEnabled = _moveUpIcon.IsEnabled = true;
                        ContentPaneHeader = _rollupDefPropertyHeader;
                        CloneAndBindingRollupDef((RollupDefinitionModel)value);
                    }
                    else if (valueType == typeof(ProductionPlanModel))
                    {
                        ContentPaneHeader = _productionPlanPropertyHeader;
                        CloneAndBindingProductionPlan((ProductionPlanModel)value);
                    }
                    else if (valueType == typeof(AlarmSettingModel))
                    {
                        ContentPaneHeader = _alarmSettingPropertyHeader;
                        CloneAndBindingAlarmSetting((AlarmSettingModel)value);
                    }
                    else if (valueType == typeof(ScheduleModel))
                    {
                        ContentPaneHeader = _schedulePropertyHeader;
                        CloneAndBindingSchedule((ScheduleModel)value);

                    }
                }

                _selectedObject = value;
                OnPropertyChanged("SelectedObject");
            }
        }

        public ObservableCollection<AreaShiftModel> AreaShifts
        {
            get { return _areaShifts; }
            set
            {
                if (_areaShifts == value) return;
                _areaShifts = value;
                OnPropertyChanged("AreaShifts");
            }
        }
        public AreaShiftModel CloneSelectedAreaShift
        {
            get { return _cloneSelectedAreaShift; }
            set
            {
                _cloneSelectedAreaShift = value;
                OnPropertyChanged("CloneSelectedAreaShift");
            }
        }

        public ObservableCollection<LaunchApplicationModel> LaunchApplications
        {
            get { return _launchApplications; }
            set
            {
                if (_launchApplications == value) return;
                _launchApplications = value;
                OnPropertyChanged("LaunchApplications");
            }
        }

        public ObservableCollection<ProductionPlanModel> ProductionPlans
        {
            get { return _productionPlans; }
            set
            {
                if (_productionPlans == value) return;
                _productionPlans = value;
                OnPropertyChanged("ProductionPlans");
            }
        }

        /// <summary>
        /// Gets or sets the start date.
        /// </summary>
        /// <value>
        /// The start date.
        /// </value>
        public DateTime StartDate
        {
            get { return _startDate; }
            set
            {
                _startDate = value;
                FilteredProductionPlans = new ObservableCollection<ProductionPlanModel>(_productionPlans.Where(
                    x => x.DueDate != null && (x.DueDate.Value.Date >= StartDate && x.DueDate.Value.Date <= EndDate)).ToList());
                OnPropertyChanged("StartDate");
            }
        }

        /// <summary>
        /// Gets or sets the end date.
        /// </summary>
        /// <value>
        /// The end date.
        /// </value>
        public DateTime EndDate
        {
            get { return _endDate; }
            set
            {
                _endDate = value;
                FilteredProductionPlans = new ObservableCollection<ProductionPlanModel>(_productionPlans.Where(
                    x => x.DueDate != null && (x.DueDate.Value.Date >= StartDate && x.DueDate.Value.Date <= EndDate)).ToList());
                OnPropertyChanged("EndDate");
            }
        }

        public ObservableCollection<ProductionPlanModel> FilteredProductionPlans
        {
            get { return _filteredProductionPlans; }
            set
            {
                _filteredProductionPlans = value;
                OnPropertyChanged("FilteredProductionPlans");
            }
        }

        public ProductionPlanReferenceModel ProductionPlanReference
        {
            get { return _productionPlanReference; }
            set
            {
                if (_productionPlanReference == value) return;
                _productionPlanReference = value;
                OnPropertyChanged("ProductionPlanReference");
            }
        }

        public LaunchApplicationModel CloneSelectedLaunchApplication
        {
            get { return _cloneSelectedLaunchApplication; }
            set
            {
                _cloneSelectedLaunchApplication = value;
                OnPropertyChanged("CloneSelectedLaunchApplication");
            }
        }

        public ObservableCollection<ReasonCodeModel> ReasonCodes
        {
            get { return _reasonCodes; }
            set
            {
                if (_reasonCodes == value) return;
                _reasonCodes = value;
                OnPropertyChanged("ReasonCodes");
            }
        }
        public ObservableCollection<RollupDefinitionModel> RollupDefinitionsSourceList
        {
            get { return _rollupDefinitionsSourceList; }
            set
            {
                if (_rollupDefinitionsSourceList == value) return;
                _rollupDefinitionsSourceList = value;
                OnPropertyChanged("RollupDefinitionsSourceList");
            }
        }
        public ObservableCollection<ReasonCodeModel> ReasonCodesSourceList
        {
            get { return _reasonCodesSourceList; }
            set
            {
                if (_reasonCodesSourceList == value) return;
                _reasonCodesSourceList = value;
                OnPropertyChanged("ReasonCodesSourceList");
            }
        }
        public ObservableCollection<ReasonCodeModel> ReasonCodesSourceComboList
        {
            get { return _reasonCodesSourceComboList; }
            set
            {
                if (_reasonCodesSourceComboList == value) return;
                _reasonCodesSourceComboList = value;
                OnPropertyChanged("ReasonCodesSourceListCombo");
            }
        }
        public ReasonCodeModel CloneSelectedReasonCode
        {
            get { return _cloneSelectedReasonCode; }
            set
            {
                _cloneSelectedReasonCode = value;
                OnPropertyChanged("CloneSelectedReasonCode");
            }
        }

        public ObservableCollection<RollupDefinitionModel> RollupDefinitions
        {
            get { return _rollupDefinitions; }
            set
            {
                if (_rollupDefinitions == value) return;
                _rollupDefinitions = value;
                OnPropertyChanged("RollupDefinitions");
            }
        }
        public RollupDefinitionModel CloneSelectedRollupDefinition
        {
            get { return _cloneSelectedRollupDefinition; }
            set
            {
                _cloneSelectedRollupDefinition = value;
                OnPropertyChanged("CloneSelectedRollupDefinition");
            }
        }

        public ObservableCollection<AlarmSettingModel> AlarmSettings
        {
            get { return _alarmSettings; }
            set
            {
                if (_alarmSettings == value) return;
                _alarmSettings = value;
                OnPropertyChanged("AlarmSettings");
            }
        }
        public AlarmSettingModel CloneSelectedAlarmSetting
        {
            get { return _cloneSelectedAlarmSetting; }
            set
            {
                _cloneSelectedAlarmSetting = value;
                OnPropertyChanged("CloneSelectedAlarmSetting");
            }
        }

        public ObservableCollection<ScheduleModel> Schedules
        {
            get { return _schedules; }
            set
            {
                if (_schedules == value) return;
                _schedules = value;
                OnPropertyChanged("Schedules");
            }

        }

        public ScheduleModel CloneSelectedSchedule
        {
            get { return _cloneSelectedSchedule; }
            set
            {
                _cloneSelectedSchedule = value;
                OnPropertyChanged("CloneSelectedSchedule");
            }
        }


        public ProductionPlanModel CloneSelectedProductionPlan
        {
            get { return _cloneSelectedProductionPlan; }
            set
            {
                _cloneSelectedProductionPlan = value;
                OnPropertyChanged("CloneSelectedProductionPlan");
            }
        }

        public ObservableCollection<ReasonCodeModel> ScrapReasonCodes
        {
            get { return _scrapReasonCodes; }
            set
            {
                if (_scrapReasonCodes == value) return;
                _scrapReasonCodes = value;
                OnPropertyChanged("ScrapReasonCodes");
            }
        }
        public ObservableCollection<ReasonCodeModel> ScrapReasonCodesSourceList
        {
            get { return _scrapReasonCodesSourceList; }
            set
            {
                if (_scrapReasonCodesSourceList == value) return;
                _scrapReasonCodesSourceList = value;
                OnPropertyChanged("ScrapReasonCodesSourceList");
            }
        }
        public ReasonCodeModel CloneSelectedScrapReasonCode
        {
            get { return _cloneSelectedScrapReasonCode; }
            set
            {
                _cloneSelectedScrapReasonCode = value;
                OnPropertyChanged("CloneSelectedScrapReasonCode");
            }
        }

        public ObservableCollection<Resource> ScheduleResources
        {


            get
            {
                return _scheduleResources
                       ?? (_scheduleResources = new ObservableCollection<Resource>
                       {
                           new Resource
                           {
                               Id = "defaultUser",
                               Name = "Default User"
                           }
                       });
            }


        }

        public ObservableCollection<ResourceCalendar> ScheduleResourceCalendars
        {
            get
            {
                return _scheduleResourceCalendars
                       ?? (_scheduleResourceCalendars = new ObservableCollection<ResourceCalendar>
                       {
                           new ResourceCalendar
                           {
                               Id = "defaultCalendar",
                               Name = "Default Calendar",
                               OwningResourceId = "defaultUser"
                           }
                       });
            }
        }

        public ObservableCollection<Appointment> ScheduledDowntimes
        {
            get { return _scheduleDowntimes; }
            set
            {
                _scheduleDowntimes = value;
                OnPropertyChanged("ScheduledDowntimes");
            }
        }

        public ObservableCollection<ScheduleRepeatModel> ScheduleRepeat
        {
            get { return _scheduleRepeatList; }
            set
            {
                if (_scheduleRepeatList == value) return;
                _scheduleRepeatList = value;
                OnPropertyChanged("ScheduleRepeat");
            }
        }

        #endregion

        #region Methods

        #region AreaShift
        private void OnAddNewAreaShift()
        {
            SelectedObject = new AreaShiftModel { IsAddNew = true, Enabled = true, };
        }

        private void DoSaveAreaShift(object obj)
        {
            if (!CloneSelectedAreaShift.IsValid())
                return;

            var areaShiftItem = new AreaShiftItem
            {
                Description = CloneSelectedAreaShift.Description.TrimSafety(),
                StartTime = new TimeSpan(CloneSelectedAreaShift.StartTime.Value.TimeOfDay.Ticks),
                EndTime = new TimeSpan(CloneSelectedAreaShift.EndTime.Value.TimeOfDay.Ticks),
                Enabled = CloneSelectedAreaShift.Enabled,
                Hidden = CloneSelectedAreaShift.Hidden,
                AreaShiftId = CloneSelectedAreaShift.AreaShiftId,
                AreaId = _currentAreaModel.AreaId,
            };

            ErrorMessage = null;
            IsBusy = true;
            if (CloneSelectedAreaShift.IsAddNew)
                DoAsync(AreaProvider.InsertAreaShift, InsertAreaShiftCompleted, areaShiftItem);
            else
                DoAsync(AreaProvider.UpdateAreaShift, UpdateAreaShiftCompleted, areaShiftItem);
        }

        private void DoCancelAreaShift(object obj)
        {
            ErrorMessage = null;
            CloneAndBindingAreaShift((AreaShiftModel)_selectedObject);
        }

        private void DoDeleteAreaShift(object obj)
        {
            ErrorMessage = null;
            if (MessageBox.Show(string.Format(FormatString.DeleteItemFormat, "shift"), TitleString.ConfirmDeleteTitle, MessageBoxButton.YesNo) == MessageBoxResult.No)
                return;

            IsBusy = true;
            DoAsync(AreaProvider.DeleteAreaShift, DeleteAreaShiftCompleted, CloneSelectedAreaShift.AreaShiftId);
        }

        private void GetAreaShiftsCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<AreaShiftItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            var list = new ObservableCollection<AreaShiftModel>();
            foreach (var item in response.Data)
            {
                list.Add(new AreaShiftModel
                {
                    AreaShiftId = item.AreaShiftId,
                    AreaId = item.AreaId,
                    Description = item.Description,
                    Enabled = item.Enabled,
                    Hidden = item.Hidden,
                    StartTime = new DateTime(item.StartTime.Ticks),
                    EndTime = new DateTime(item.EndTime.Ticks),
                    CreatedBy = item.CreatedBy,
                    CreatedDate = item.CreatedDate.ToString(FormatString.DateTimeFormat),
                    LastUpdatedBy = item.LastUpdatedBy,
                    LastUpdatedDate = item.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
                });
            }
            AreaShifts = list;

        }

        private void InsertAreaShiftCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<AreaShiftItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedAreaShift.ErrorMessage = response.Error.Description;

                CloneSelectedAreaShift.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var newAreaShift = new AreaShiftModel
                {
                    AreaShiftId = response.Data.AreaShiftId,
                    AreaId = response.Data.AreaId,
                    Description = response.Data.Description,
                    Enabled = response.Data.Enabled,
                    Hidden = response.Data.Hidden,
                    StartTime = new DateTime(response.Data.StartTime.Ticks),
                    EndTime = new DateTime(response.Data.EndTime.Ticks),
                    CreatedBy = response.Data.CreatedBy,
                    CreatedDate = response.Data.CreatedDate.ToString(FormatString.DateTimeFormat),
                    LastUpdatedBy = response.Data.LastUpdatedBy,
                    LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
                };

            AreaShifts.Add(newAreaShift);

            _selectedObject = null;
            SelectedObject = newAreaShift;

            SetPendingObject();
        }

        private void UpdateAreaShiftCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<AreaShiftItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedAreaShift.ErrorMessage = response.Error.Description;

                CloneSelectedAreaShift.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var selectedAreaShift = (AreaShiftModel)_selectedObject;

            selectedAreaShift.Description = response.Data.Description;
            selectedAreaShift.StartTime = new DateTime(response.Data.StartTime.Ticks);
            selectedAreaShift.EndTime = new DateTime(response.Data.EndTime.Ticks);
            selectedAreaShift.Enabled = response.Data.Enabled;
            selectedAreaShift.Hidden = response.Data.Hidden;
            selectedAreaShift.LastUpdatedBy = response.Data.LastUpdatedBy;
            selectedAreaShift.LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat);

            selectedAreaShift.IsChange = false;
            selectedAreaShift.ErrorMessage = null;
            selectedAreaShift.IsCancelEnable = false;
            CloneAndBindingAreaShift(selectedAreaShift);

            SetPendingObject();
        }

        private void DeleteAreaShiftCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as DeleteDataResponse;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                CloneSelectedAreaShift.ErrorMessage = response.Error.Description;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            CloneSelectedAreaShift = null;
            SelectedObject = null;

            var item = AreaShifts.FirstOrDefault(t => t.AreaShiftId == response.DataId);
            if (item != null)
                AreaShifts.Remove(item);
        }

        public void CloneAndBindingAreaShift(AreaShiftModel value)
        {
            CloneSelectedAreaShift = SmartReflection.CloneModel(value);
            CloneSelectedAreaShift.ShouldValidate = true;
        }
        #endregion

        #region LaunchApplication
        private void OnAddNewApplication()
        {
            var lastItem = LaunchApplications.OrderByDescending(t => t.SortOrder).FirstOrDefault();
            SelectedObject = new LaunchApplicationModel
            {
                IsAddNew = true,
                Enabled = true,
                SortOrder = lastItem != null ? (lastItem.SortOrder + 1) : 0,
            };
        }

        private void OnAddNewProductionPlan()
        {
            var lastItem = ProductionPlans.OrderByDescending(t => t.SortOrder).FirstOrDefault();
            SelectedObject = new ProductionPlanModel
            {
                IsAddNew = true,
                Enabled = true,
                SortOrder = lastItem != null ? (lastItem.SortOrder + 1) : 0,
            };
        }

        private void OnAddNewScheduledDowntime()
        {
            //var lastItem = Schedules.OrderByDescending(t=>t.s)
            SelectedObject = new ScheduleModel() { IsAddNew = true };
        }

        private void OnMoveDownApplication()
        {
            if (CloneSelectedLaunchApplication == null || LaunchApplications.IndexOf(LaunchApplications.FirstOrDefault(t => t.LaunchApplicationId == CloneSelectedLaunchApplication.LaunchApplicationId)) == (LaunchApplications.Count - 1))
                return;

            var movingLa = new LaunchApplicationItem
            {
                LaunchApplicationId = CloneSelectedLaunchApplication.LaunchApplicationId,
                AreaId = _currentAreaModel.AreaId,
                SortOrder = 1,
            };

            DoAsync(AreaProvider.MoveLaunchApplication, MoveLaunchApplicationCompleted, movingLa);
        }

        private void OnMoveUpApplication()
        {
            if (CloneSelectedLaunchApplication == null || LaunchApplications.IndexOf(LaunchApplications.FirstOrDefault(t => t.LaunchApplicationId == CloneSelectedLaunchApplication.LaunchApplicationId)) == 0)
                return;

            var movingLa = new LaunchApplicationItem
            {
                LaunchApplicationId = CloneSelectedLaunchApplication.LaunchApplicationId,
                AreaId = _currentAreaModel.AreaId,
                SortOrder = -1,
            };

            DoAsync(AreaProvider.MoveLaunchApplication, MoveLaunchApplicationCompleted, movingLa);
        }

        private void DoSaveLaunchApplication(object obj)
        {
            if (!CloneSelectedLaunchApplication.IsValid())
                return;

            var launchApplicationItem = new LaunchApplicationItem
            {
                Description = CloneSelectedLaunchApplication.Description,
                Application = CloneSelectedLaunchApplication.Application,
                Arguments = CloneSelectedLaunchApplication.Arguments,
                SortOrder = CloneSelectedLaunchApplication.SortOrder,
                Enabled = CloneSelectedLaunchApplication.Enabled,
                LaunchApplicationId = CloneSelectedLaunchApplication.LaunchApplicationId,
                AreaId = _currentAreaModel.AreaId,
            };

            ErrorMessage = null;
            IsBusy = true;
            if (CloneSelectedLaunchApplication.IsAddNew)
                DoAsync(AreaProvider.InsertLaunchApplication, InsertLaunchApplicationCompleted, launchApplicationItem);
            else
                DoAsync(AreaProvider.UpdateLaunchApplication, UpdateLaunchApplicationCompleted, launchApplicationItem);
        }

        private void DoCancelLaunchApplication(object obj)
        {
            ErrorMessage = null;
            CloneAndBindingLaunchApplication((LaunchApplicationModel)_selectedObject);
        }

        private void DoDeleteLaunchApplication(object obj)
        {
            ErrorMessage = null;
            if (MessageBox.Show(string.Format(FormatString.DeleteItemFormat, "application"), TitleString.ConfirmDeleteTitle, MessageBoxButton.YesNo) == MessageBoxResult.No)
                return;

            IsBusy = true;
            DoAsync(AreaProvider.DeleteLaunchApplication, DeleteLaunchApplicationCompleted, CloneSelectedLaunchApplication.LaunchApplicationId);
        }

        private void GetLaunchApplicationsCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<LaunchApplicationItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            var list = new ObservableCollection<LaunchApplicationModel>();
            foreach (var item in response.Data)
            {
                list.Add(new LaunchApplicationModel
                {
                    LaunchApplicationId = item.LaunchApplicationId,
                    AreaId = item.AreaId,
                    Description = item.Description,
                    Enabled = item.Enabled,
                    Application = item.Application,
                    Arguments = item.Arguments,
                    SortOrder = item.SortOrder,
                    CreatedBy = item.CreatedBy,
                    CreatedDate = item.CreatedDate.ToString(FormatString.DateTimeFormat),
                    LastUpdatedBy = item.LastUpdatedBy,
                    LastUpdatedDate = item.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
                });
            }
            LaunchApplications = list;
        }

        private void InsertLaunchApplicationCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<LaunchApplicationItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedLaunchApplication.ErrorMessage = response.Error.Description;

                CloneSelectedLaunchApplication.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var newLaunchApplication = new LaunchApplicationModel
            {
                AreaId = response.Data.AreaId,
                Arguments = response.Data.Arguments,
                Application = response.Data.Application,
                Description = response.Data.Description,
                SortOrder = response.Data.SortOrder,
                Enabled = response.Data.Enabled,
                CreatedBy = response.Data.CreatedBy,
                CreatedDate = response.Data.CreatedDate.ToString(FormatString.DateTimeFormat),
                LastUpdatedBy = response.Data.LastUpdatedBy,
                LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
            };

            LaunchApplications.Add(newLaunchApplication);

            _selectedObject = null;
            SelectedObject = newLaunchApplication;

            SetPendingObject();
        }

        private void UpdateLaunchApplicationCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<LaunchApplicationItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedLaunchApplication.ErrorMessage = response.Error.Description;

                CloneSelectedLaunchApplication.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var selectedLaunchApplication = (LaunchApplicationModel)_selectedObject;

            selectedLaunchApplication.Description = response.Data.Description;
            selectedLaunchApplication.Arguments = response.Data.Arguments;
            selectedLaunchApplication.Application = response.Data.Application;
            selectedLaunchApplication.SortOrder = response.Data.SortOrder;
            selectedLaunchApplication.Enabled = response.Data.Enabled;
            selectedLaunchApplication.LastUpdatedBy = response.Data.LastUpdatedBy;
            selectedLaunchApplication.LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat);

            selectedLaunchApplication.IsChange = false;
            selectedLaunchApplication.ErrorMessage = null;
            selectedLaunchApplication.IsCancelEnable = false;
            CloneAndBindingLaunchApplication(selectedLaunchApplication);

            SetPendingObject();
        }

        private void DeleteLaunchApplicationCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as DeleteDataResponse;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                CloneSelectedLaunchApplication.ErrorMessage = response.Error.Description;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            CloneSelectedLaunchApplication = null;
            SelectedObject = null;

            var item = LaunchApplications.FirstOrDefault(t => t.LaunchApplicationId == response.DataId);
            if (item != null)
                LaunchApplications.Remove(item);
        }

        private void MoveLaunchApplicationCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<IList<LaunchApplicationItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedLaunchApplication.ErrorMessage = response.Error.Description;
                return;
            }

            foreach (var item in response.Data)
            {
                var laModel = LaunchApplications.FirstOrDefault(t => t.LaunchApplicationId == item.LaunchApplicationId);
                if (laModel != null)
                    laModel.SortOrder = item.SortOrder;
            }

            var temp = SelectedObject;
            var tempList = LaunchApplications.OrderBy(t => t.SortOrder).ToList();
            LaunchApplications.Clear();
            foreach (var la in tempList)
                LaunchApplications.Add(la);
            SelectedObject = temp;
        }

        private void CloneAndBindingLaunchApplication(LaunchApplicationModel value)
        {
            CloneSelectedLaunchApplication = SmartReflection.CloneModel(value);
            CloneSelectedLaunchApplication.ShouldValidate = true;
        }
        #endregion

        #region ReasonCode

        private void OnParentReasonCodeClick(Object obj)
        {
            if (ParentReasonTreeVisibility == Visibility.Collapsed)
            {
                ParentReasonTreeVisibility = Visibility.Visible;
                ParentReasonTreeButtonContent = "Hide";
            }
            else
            {
                ParentReasonTreeVisibility = Visibility.Collapsed;
                ParentReasonTreeButtonContent = "Show";
            }
        }

        private void OnLinkReasonCodeClick(Object obj)
        {
            if (LinkReasonTreeVisibility == Visibility.Collapsed)
            {
                LinkReasonTreeVisibility = Visibility.Visible;
                LinkReasonTreeButtonContent = "Hide";
            }
            else
            {
                LinkReasonTreeVisibility = Visibility.Collapsed;
                LinkReasonTreeButtonContent = "Show";
            }
        }


        private void OnAddNewReasonCode()
        {
            SelectedObject = new ReasonCodeModel { IsAddNew = true, };
        }

        private void DoSaveReasonCode(object obj)
        {
            if (CloneSelectedReasonCode.Link != null && CloneSelectedReasonCode.LinkId > 0)
            {
                if (string.IsNullOrEmpty(CloneSelectedReasonCode.Description))
                    CloneSelectedReasonCode.Description = CloneSelectedReasonCode.Link.Description;

                CloneSelectedReasonCode.RollupDefinitionId = CloneSelectedReasonCode.Link.RollupDefinitionId;
                CloneSelectedReasonCode.RollupDefinition = CloneSelectedReasonCode.Link.RollupDefinition;
            }

            if (!CloneSelectedReasonCode.IsValid())
                return;

            var rcItem = new ReasonCodeItem
            {
                ReasonCodeId = CloneSelectedReasonCode.ReasonCodeId,
                AreaId = _currentAreaModel.AreaId,
                Description = CloneSelectedReasonCode.Description.TrimSafety(),
                ParentId = CloneSelectedReasonCode.ParentId == 0 ? null : CloneSelectedReasonCode.ParentId,
                LinkId = CloneSelectedReasonCode.LinkId == 0 ? null : CloneSelectedReasonCode.LinkId,
                Level = CloneSelectedReasonCode.Parent != null ? (CloneSelectedReasonCode.Parent.Level + 1) : 1,
                RollupDefinitionId = CloneSelectedReasonCode.RollupDefinitionId == 0 ? null : CloneSelectedReasonCode.RollupDefinitionId,
                Category = (ReasonCodeItem.ReasonCodeCategory)CloneSelectedReasonCode.Category,
                IgnoreVisiBoxEvents = CloneSelectedReasonCode.IgnoreVisiBoxEvents,
                HideChildren = CloneSelectedReasonCode.HideChildren,
                FlashDelay = CloneSelectedReasonCode.FlashDelay,
                Scrap = CloneSelectedReasonCode.Scrap,
                DisplayInDowntimeChart = CloneSelectedReasonCode.DisplayInDowntimeChart,
                IgnoreInOeeCalc = CloneSelectedReasonCode.IgnoreInOeeCalc,
                IgnoreInWaitingCalc = CloneSelectedReasonCode.IgnoreInWaitingCalc,
                ShopClockEvent = CloneSelectedReasonCode.ShopClockEvent
            };

            ErrorMessage = null;
            IsBusy = true;
            if (CloneSelectedReasonCode.IsAddNew)
                DoAsync(AreaProvider.InsertReasonCode, InsertReasonCodeCompleted, rcItem);
            else
                DoAsync(AreaProvider.UpdateReasonCode, UpdateReasonCodeCompleted, rcItem);
        }

        private void DoCancelReasonCode(object obj)
        {
            ErrorMessage = null;
            CloneAndBindingReasonCode((ReasonCodeModel)_selectedObject);
        }

        private void DoDeleteReasonCode(object obj)
        {
            ErrorMessage = null;
            if (MessageBox.Show(string.Format(FormatString.DeleteItemFormat, "reason code"), TitleString.ConfirmDeleteTitle, MessageBoxButton.YesNo) == MessageBoxResult.No)
                return;

            IsBusy = true;
            DoAsync(AreaProvider.DeleteReasonCode, DeleteReasonCodeCompleted, CloneSelectedReasonCode.ReasonCodeId);
        }

        private void GetRollupDefinitionsAsSourceCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<RollupDefinitionItem>>;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            var list = new ObservableCollection<RollupDefinitionModel>();
            foreach (var item in response.Data)
            {
                list.Add(new RollupDefinitionModel
                {
                    RollupDefinitionId = item.RollupDefinitionId,
                    Description = item.Description,
                });
            }
            RollupDefinitionsSourceList = list;

            if (ReasonCodes == null)
                DoAsync(AreaProvider.GetReasonCodes, GetReasonCodesCompleted, _currentAreaModel.AreaId);
            else
            {
                IsBusy = false;
                UpdateRollupDefitionForReasonCode(ReasonCodes);
            }
        }

        private void GetReasonCodesCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<ReasonCodeItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            var list = new ObservableCollection<ReasonCodeModel>();
            foreach (var item in response.Data.Where(t => t.Level == 1))
            {
                var rcm = CreateReasonCodeNode(item, response.Data);
                list.Add(rcm);
            }

            //var listCombo = new ObservableCollection<ReasonCodeModel>();
            //foreach (var item in response.Data)
            //{
            //    listCombo.Add(new ReasonCodeModel
            //    {
            //        ReasonCodeId = item.ReasonCodeId,
            //        Description = item.Description,
            //    });
            //}
            //ReasonCodesSourceComboList = listCombo;

            ReasonCodes = list;
        }

        private void InsertReasonCodeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<ReasonCodeItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedReasonCode.ErrorMessage = response.Error.Description;

                CloneSelectedReasonCode.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var newReasonCode = CreateReasonCodeNode(response.Data, null);

            //Add to new parent
            var newParent = FindNode(response.Data.ParentId ?? 0, ReasonCodes);
            if (newParent != null)
            {
                if (newParent.Children == null)
                    newParent.Children = new ObservableCollection<ReasonCodeModel>();
                newParent.Children.Add(newReasonCode);
            }
            else
            {
                if (ReasonCodes == null)
                    ReasonCodes = new ObservableCollection<ReasonCodeModel>();
                ReasonCodes.Add(newReasonCode);
            }

            _selectedObject = null;
            SelectedObject = newReasonCode;

            SetPendingObject();
        }

        private void UpdateReasonCodeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<ReasonCodeItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedReasonCode.ErrorMessage = response.Error.Description;

                CloneSelectedReasonCode.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }


            var selectedReasonCode = (ReasonCodeModel)_selectedObject;
            _selectedObject = null;

            var oldParentId = selectedReasonCode.ParentId ?? 0;
            var newParentId = response.Data.ParentId ?? 0;
            if (oldParentId != newParentId)
            {
                //Remove from old parent
                var oldParent = FindNode(oldParentId, ReasonCodes);
                if (oldParent != null && oldParent.Children != null)
                    oldParent.Children.Remove(oldParent.Children.FirstOrDefault(t => t.ReasonCodeId == selectedReasonCode.ReasonCodeId));
                else if (ReasonCodes != null)
                    ReasonCodes.Remove(ReasonCodes.FirstOrDefault(t => t.ReasonCodeId == selectedReasonCode.ReasonCodeId));

                //Add to new parent
                var newParent = FindNode(newParentId, ReasonCodes);
                if (newParent != null)
                {
                    if (newParent.Children == null)
                        newParent.Children = new ObservableCollection<ReasonCodeModel>();
                    newParent.Children.Add(selectedReasonCode);
                }
                else
                {
                    if (ReasonCodes == null)
                        ReasonCodes = new ObservableCollection<ReasonCodeModel>();
                    ReasonCodes.Add(selectedReasonCode);
                }
            }

            selectedReasonCode.Description = response.Data.Description;
            selectedReasonCode.ParentId = response.Data.ParentId;
            selectedReasonCode.LinkId = response.Data.LinkId;
            selectedReasonCode.RollupDefinition = RollupDefinitionsSourceList.FirstOrDefault(t => t.RollupDefinitionId == response.Data.RollupDefinitionId);
            selectedReasonCode.Level = response.Data.Level;
            selectedReasonCode.Category = (ReasonCodeItem.ReasonCodeCategory)response.Data.Category;
            selectedReasonCode.IgnoreVisiBoxEvents = response.Data.IgnoreVisiBoxEvents;
            selectedReasonCode.HideChildren = response.Data.HideChildren;
            selectedReasonCode.FlashDelay = response.Data.FlashDelay;
            selectedReasonCode.DisplayInDowntimeChart = response.Data.DisplayInDowntimeChart;
            selectedReasonCode.IgnoreInOeeCalc = response.Data.IgnoreInOeeCalc;
            selectedReasonCode.IgnoreInWaitingCalc = response.Data.IgnoreInWaitingCalc;
            selectedReasonCode.LastUpdatedBy = response.Data.LastUpdatedBy;
            selectedReasonCode.LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat);
            selectedReasonCode.ShopClockEvent = response.Data.ShopClockEvent;

            selectedReasonCode.IsChange = false;
            selectedReasonCode.ErrorMessage = null;
            selectedReasonCode.IsCancelEnable = false;

            SelectedObject = selectedReasonCode;
            SetPendingObject();
        }

        private void DeleteReasonCodeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as DeleteDataResponse;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                CloneSelectedReasonCode.ErrorMessage = response.Error.Description;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var parentId = ((ReasonCodeModel)SelectedObject).ParentId ?? 0;
            CloneSelectedReasonCode = null;
            SelectedObject = null;

            //Remove from old parent
            var oldParent = FindNode(parentId, ReasonCodes);
            if (oldParent != null && oldParent.Children != null)
                oldParent.Children.Remove(oldParent.Children.FirstOrDefault(t => t.ReasonCodeId == response.DataId));
            else if (ReasonCodes != null)
                ReasonCodes.Remove(ReasonCodes.FirstOrDefault(t => t.ReasonCodeId == response.DataId));
        }

        private ReasonCodeModel CreateReasonCodeNode(ReasonCodeItem item, IList<ReasonCodeItem> list)
        {
            var rc = new ReasonCodeModel
            {
                ReasonCodeId = item.ReasonCodeId,
                AreaId = item.AreaId,
                ParentId = item.ParentId,
                LinkId = item.LinkId,
                RollupDefinition = RollupDefinitionsSourceList != null ?
                    RollupDefinitionsSourceList.FirstOrDefault(t => t.RollupDefinitionId == item.RollupDefinitionId) : null,
                Level = item.Level,
                Description = item.Description,
                CreatedBy = item.CreatedBy,
                LastUpdatedBy = item.LastUpdatedBy,
                CreatedDate = item.CreatedDate.ToString(FormatString.DateTimeFormat),
                LastUpdatedDate = item.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
                IgnoreVisiBoxEvents = item.IgnoreVisiBoxEvents,
                Category = (ReasonCodeItem.ReasonCodeCategory)item.Category,
                HideChildren = item.HideChildren,
                FlashDelay = item.FlashDelay,
                DisplayInDowntimeChart = item.DisplayInDowntimeChart,
                IgnoreInOeeCalc = item.IgnoreInOeeCalc,
                IgnoreInWaitingCalc = item.IgnoreInWaitingCalc,
                Children = new ObservableCollection<ReasonCodeModel>(),
                Scrap = item.Scrap,
                ShopClockEvent = item.ShopClockEvent
            };

            if (list != null)
                foreach (var child in list.Where(t => t.ParentId == rc.ReasonCodeId))
                {
                    rc.Children.Add(CreateReasonCodeNode(child, list));
                }
            return rc;
        }

        private void CreateReasonCodesAsSource(int reasonCodeId)
        {
            if (ReasonCodes == null)
                return;

            ReasonCodesSourceList = new ObservableCollection<ReasonCodeModel>() { new ReasonCodeModel { ReasonCodeId = 0, Description = "- No Parent -", Children = new ObservableCollection<ReasonCodeModel>(), } };
            foreach (var rc in ReasonCodes)
            {
                if (rc.ReasonCodeId == reasonCodeId)
                    continue;

                ReasonCodesSourceList[0].Children.Add(CreateReasonCodeNodeForSource(reasonCodeId, rc));
            }
        }

        private ReasonCodeModel CreateReasonCodeNodeForSource(int reasonCodeId, ReasonCodeModel rc)
        {
            var rcm = new ReasonCodeModel
            {
                ReasonCodeId = rc.ReasonCodeId,
                Description = rc.Description,
                Level = rc.Level,
                Children = new ObservableCollection<ReasonCodeModel>(),
            };

            if (rc.Children != null)
                foreach (var child in rc.Children)
                {
                    if (child.ReasonCodeId == reasonCodeId)
                        continue;

                    rcm.Children.Add(CreateReasonCodeNodeForSource(reasonCodeId, child));
                }
            return rcm;
        }

        private ReasonCodeModel FindNode(int reasonCodeId, ObservableCollection<ReasonCodeModel> list)
        {
            foreach (var item in list)
            {
                if (item.ReasonCodeId == reasonCodeId)
                    return item;

                var child = FindNode(reasonCodeId, item.Children);
                if (child != null)
                    return child;
            }
            return null;
        }

        private void UpdateRollupDefitionForReasonCode(ObservableCollection<ReasonCodeModel> list)
        {
            if (list == null) return;
            foreach (var reasonCode in list)
            {
                reasonCode.RollupDefinition = RollupDefinitionsSourceList.FirstOrDefault(t => t.RollupDefinitionId == reasonCode.RollupDefinitionId);
                if (reasonCode.Children != null)
                    UpdateRollupDefitionForReasonCode(reasonCode.Children);
            }
        }

        private void CloneAndBindingReasonCode(ReasonCodeModel value)
        {
            CreateReasonCodesAsSource(value.ReasonCodeId);
            CloneSelectedReasonCode = SmartReflection.CloneModel(value);
            CloneSelectedReasonCode.RollupDefinition = RollupDefinitionsSourceList.FirstOrDefault(t => t.RollupDefinitionId == CloneSelectedReasonCode.RollupDefinitionId);
            CloneSelectedReasonCode.Parent = FindNode(CloneSelectedReasonCode.ParentId ?? 0, ReasonCodesSourceList);
            CloneSelectedReasonCode.Link = FindNode(CloneSelectedReasonCode.LinkId ?? 0, ReasonCodesSourceList);
            CloneSelectedReasonCode.ShouldValidate = true;
        }

        #endregion

        #region RollupDefinition

        private void OnAddNewRollupDef()
        {
            var lastItem = RollupDefinitions.OrderByDescending(t => t.SortOrder).FirstOrDefault();

            SelectedObject = new RollupDefinitionModel
            {
                IsAddNew = true,
                SortOrder = lastItem != null ? (lastItem.SortOrder + 1) : 0,
            };
        }

        private void OnMoveUpRollupDef()
        {
            if (CloneSelectedRollupDefinition == null || RollupDefinitions.IndexOf(RollupDefinitions.FirstOrDefault(t => t.RollupDefinitionId == CloneSelectedRollupDefinition.RollupDefinitionId)) == 0)
                return;

            var movingRd = new RollupDefinitionItem
            {
                RollupDefinitionId = CloneSelectedRollupDefinition.RollupDefinitionId,
                AreaId = _currentAreaModel.AreaId,
                SortOrder = -1,
            };

            DoAsync(AreaProvider.MoveRollupDefinition, MoveRollupDefinitionCompleted, movingRd);
        }

        private void OnMoveDownRollupDef()
        {
            if (CloneSelectedRollupDefinition == null || RollupDefinitions.IndexOf(RollupDefinitions.FirstOrDefault(t => t.RollupDefinitionId == CloneSelectedRollupDefinition.RollupDefinitionId)) == (RollupDefinitions.Count - 1))
                return;

            var movingRd = new RollupDefinitionItem
            {
                RollupDefinitionId = CloneSelectedRollupDefinition.RollupDefinitionId,
                AreaId = _currentAreaModel.AreaId,
                SortOrder = 1,
            };

            DoAsync(AreaProvider.MoveRollupDefinition, MoveRollupDefinitionCompleted, movingRd);
        }

        private void DoSaveRollupDef(object obj)
        {
            //TODO: font color and color mix up

            if (!CloneSelectedRollupDefinition.IsValid())
                return;

            var rdItem = new RollupDefinitionItem
            {
                RollupDefinitionId = CloneSelectedRollupDefinition.RollupDefinitionId,
                AreaId = _currentAreaModel.AreaId,
                Description = CloneSelectedRollupDefinition.Description.TrimSafety(),
                SortOrder = CloneSelectedRollupDefinition.SortOrder,
                Color = CloneSelectedRollupDefinition.ColorString,
                FontColor = CloneSelectedRollupDefinition.FontColorString,
                FlashingTimeout = CloneSelectedRollupDefinition.FlashingTimeout,
            };

            ErrorMessage = null;
            // IsBusy = true;
            if (CloneSelectedRollupDefinition.IsAddNew)
                DoAsync(AreaProvider.InsertRollupDef, InsertRollupDefCompleted, rdItem);
            else
                DoAsync(AreaProvider.UpdateRollupDef, UpdateRollupDefCompleted, rdItem);
        }

        private void DoCancelRollupDef(object obj)
        {
            ErrorMessage = null;
            CloneAndBindingRollupDef((RollupDefinitionModel)_selectedObject);
        }

        private void DoDeleteRollupDef(object obj)
        {
            ErrorMessage = null;
            if (MessageBox.Show(string.Format(FormatString.DeleteItemFormat, "rollup definition"), TitleString.ConfirmDeleteTitle, MessageBoxButton.YesNo) == MessageBoxResult.No)
                return;

            IsBusy = true;
            DoAsync(AreaProvider.DeleteRollupDef, DeleteRollupDefCompleted, CloneSelectedRollupDefinition.RollupDefinitionId);
        }

        private void GetRollupDefinitionsCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<RollupDefinitionItem>>;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                IsBusy = false;
                return;
            }

            var list = new ObservableCollection<RollupDefinitionModel>();
            foreach (var item in response.Data)
            {
                var rud = new RollupDefinitionModel
                {
                    RollupDefinitionId = item.RollupDefinitionId,
                    AreaId = item.AreaId,
                    Description = item.Description,
                    ColorString = item.Color,
                    SortOrder = item.SortOrder,
                    FontColorString = item.FontColor,
                    FlashingTimeout = item.FlashingTimeout,
                    CreatedBy = item.CreatedBy,
                    CreatedDate = item.CreatedDate.ToString(FormatString.DateTimeFormat),
                    LastUpdatedBy = item.LastUpdatedBy,
                    LastUpdatedDate = item.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
                };
                list.Add(rud);
            }
            RollupDefinitions = list;

            IsBusy = false;
        }

        private void InsertRollupDefCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<RollupDefinitionItem>;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                    CloneSelectedRollupDefinition.ErrorMessage = response.Error.Description;

                CloneSelectedRollupDefinition.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }

            var newRollupDefinition = new RollupDefinitionModel
            {
                RollupDefinitionId = response.Data.RollupDefinitionId,
                AreaId = response.Data.AreaId,
                Description = response.Data.Description,
                ColorString = response.Data.Color,
                SortOrder = response.Data.SortOrder,
                FontColorString = response.Data.FontColor,
                FlashingTimeout = response.Data.FlashingTimeout,
                CreatedBy = response.Data.CreatedBy,
                CreatedDate = response.Data.CreatedDate.ToString(FormatString.DateTimeFormat),
                LastUpdatedBy = response.Data.LastUpdatedBy,
                LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
            };

            RollupDefinitions.Add(newRollupDefinition);

            _selectedObject = null;
            SelectedObject = newRollupDefinition;

            SetPendingObject();

            //Refresh RollupDefinitions Source List
            DoAsync(AreaProvider.GetRollupDefinitionsAsSource, GetRollupDefinitionsAsSourceCompleted, _currentAreaModel.AreaId);
        }

        private void UpdateRollupDefCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<RollupDefinitionItem>;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                    CloneSelectedRollupDefinition.ErrorMessage = response.Error.Description;

                CloneSelectedRollupDefinition.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }

            var selectedRollupDefinition = (RollupDefinitionModel)_selectedObject;

            selectedRollupDefinition.Description = response.Data.Description;
            selectedRollupDefinition.ColorString = response.Data.Color;
            selectedRollupDefinition.SortOrder = response.Data.SortOrder;
            selectedRollupDefinition.FontColorString = response.Data.FontColor;
            selectedRollupDefinition.FlashingTimeout = response.Data.FlashingTimeout;
            selectedRollupDefinition.LastUpdatedBy = response.Data.LastUpdatedBy;
            selectedRollupDefinition.LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat);

            selectedRollupDefinition.IsChange = false;
            selectedRollupDefinition.ErrorMessage = null;
            selectedRollupDefinition.IsCancelEnable = false;
            CloneAndBindingRollupDef(selectedRollupDefinition);

            SetPendingObject();

            //Refresh RollupDefinitions Source List
            DoAsync(AreaProvider.GetRollupDefinitionsAsSource, GetRollupDefinitionsAsSourceCompleted, _currentAreaModel.AreaId);
        }

        private void DeleteRollupDefCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as DeleteDataResponse;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                CloneSelectedRollupDefinition.ErrorMessage = response.Error.Description;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }

            CloneSelectedRollupDefinition = null;
            SelectedObject = null;

            var item = RollupDefinitions.FirstOrDefault(t => t.RollupDefinitionId == response.DataId);
            if (item != null)
                RollupDefinitions.Remove(item);

            //Refresh RollupDefinitions Source List
            DoAsync(AreaProvider.GetRollupDefinitionsAsSource, GetRollupDefinitionsAsSourceCompleted, _currentAreaModel.AreaId);
        }

        private void MoveRollupDefinitionCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<IList<RollupDefinitionItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedRollupDefinition.ErrorMessage = response.Error.Description;
                return;
            }

            foreach (var item in response.Data)
            {
                var rdModel = RollupDefinitions.FirstOrDefault(t => t.RollupDefinitionId == item.RollupDefinitionId);
                if (rdModel != null)
                    rdModel.SortOrder = item.SortOrder;

                rdModel = RollupDefinitionsSourceList.FirstOrDefault(t => t.RollupDefinitionId == item.RollupDefinitionId);
                if (rdModel != null)
                    rdModel.SortOrder = item.SortOrder;
            }

            var temp = SelectedObject;
            var tempList = RollupDefinitions.OrderBy(t => t.SortOrder).ToList();
            RollupDefinitions.Clear();
            foreach (var rd in tempList)
                RollupDefinitions.Add(rd);
            SelectedObject = temp;


            tempList = RollupDefinitionsSourceList.OrderBy(t => t.SortOrder).ToList();
            RollupDefinitionsSourceList.Clear();
            foreach (var rd in tempList)
                RollupDefinitionsSourceList.Add(rd);
        }

        private void CloneAndBindingRollupDef(RollupDefinitionModel value)
        {
            CloneSelectedRollupDefinition = SmartReflection.CloneModel(value);

            if (!CloneSelectedRollupDefinition.IsAddNew)
            {
                CloneSelectedRollupDefinition.FontColorString = value.FontColorString;
                CloneSelectedRollupDefinition.ColorString = value.ColorString;
            }

            CloneSelectedRollupDefinition.ShouldValidate = true;
        }

        #endregion

        #region Alarm Settings

        private void OnAddNewAlarmSetting()
        {
            SelectedObject = new AlarmSettingModel
            {
                IsAddNew = true,
            };
        }

        private void DoDeleteAlarmSetting(object obj)
        {
            ErrorMessage = null;
            if (MessageBox.Show(string.Format(FormatString.DeleteItemFormat, "alarm setting"), TitleString.ConfirmDeleteTitle, MessageBoxButton.YesNo) == MessageBoxResult.No)
                return;

            IsBusy = true;
            DoAsync(AreaProvider.DeleteAlarmSetting, DeleteAlarmSettingCompleted, CloneSelectedAlarmSetting.AlarmSettingId);
        }





        private void DeleteAlarmSettingCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as DeleteDataResponse;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                {
                    CloneSelectedAlarmSetting.ErrorMessage = response.Error.Description;
                }
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }

            CloneSelectedAlarmSetting = null;
            SelectedObject = null;

            var item = AlarmSettings.FirstOrDefault(t => t.AlarmSettingId == response.DataId);
            if (item != null)
                AlarmSettings.Remove(item);
            IsBusy = false;
        }

        private void DoCancelAlarmSetting(object obj)
        {
            ErrorMessage = null;
            CloneAndBindingAlarmSetting((AlarmSettingModel)_selectedObject);
        }

        private void DoSaveAlarmSetting(object obj)
        {
            if (!CloneSelectedAlarmSetting.IsValid())
                return;

            var rdItem = new AlarmSettingItem
            {
                AlarmSettingId = CloneSelectedAlarmSetting.AlarmSettingId,
                AreaId = _currentAreaModel.AreaId,
                MinPercentageGood = CloneSelectedAlarmSetting.MinPercentageGood,
                Color = CloneSelectedAlarmSetting.ColorString,
                FontColor = CloneSelectedAlarmSetting.FontColorString,
                MinPercentageBad = CloneSelectedAlarmSetting.MinPercentageBad,
            };
            ErrorMessage = null;
            //  IsBusy = true;
            if (CloneSelectedAlarmSetting.IsAddNew)
                DoAsync(AreaProvider.InsertAlarmSetting, InsertAlarmSettingCompleted, rdItem);
            else
                DoAsync(AreaProvider.UpdateAlarmSetting, UpdateAlarmSettingCompleted, rdItem);
        }

        private void UpdateAlarmSettingCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<AlarmSettingItem>;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                    CloneSelectedRollupDefinition.ErrorMessage = response.Error.Description;

                CloneSelectedRollupDefinition.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }

            var alarmSettingModel = (AlarmSettingModel)_selectedObject;

            alarmSettingModel.ColorString = response.Data.Color;
            alarmSettingModel.MinPercentageBad = response.Data.MinPercentageBad;
            alarmSettingModel.FontColorString = response.Data.FontColor;
            alarmSettingModel.MinPercentageGood = response.Data.MinPercentageGood;
            alarmSettingModel.LastUpdatedBy = response.Data.LastUpdatedBy;
            alarmSettingModel.LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat);

            alarmSettingModel.IsChange = false;
            alarmSettingModel.ErrorMessage = null;
            alarmSettingModel.IsCancelEnable = false;
            CloneAndBindingAlarmSetting(alarmSettingModel);

            SetPendingObject();
            IsBusy = false;
        }

        private void InsertAlarmSettingCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<AlarmSettingItem>;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                    CloneSelectedAlarmSetting.ErrorMessage = response.Error.Description;

                CloneSelectedAlarmSetting.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }

            var newAlarmSetting = new AlarmSettingModel
            {
                AlarmSettingId = response.Data.AlarmSettingId,
                AreaId = response.Data.AreaId,
                ColorString = response.Data.Color,
                MinPercentageGood = response.Data.MinPercentageGood,
                FontColorString = response.Data.FontColor,
                MinPercentageBad = response.Data.MinPercentageBad,
                CreatedBy = response.Data.CreatedBy,
                CreatedDate = response.Data.CreatedDate.ToString(FormatString.DateTimeFormat),
                LastUpdatedBy = response.Data.LastUpdatedBy,
                LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
            };

            AlarmSettings.Add(newAlarmSetting);

            _selectedObject = null;
            SelectedObject = newAlarmSetting;

            SetPendingObject();
            IsBusy = false;
        }

        private void GetAlarmSettingsCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<AlarmSettingItem>>;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                IsBusy = false;
                return;
            }

            var list = new ObservableCollection<AlarmSettingModel>();
            foreach (var item in response.Data)
            {
                var rud = new AlarmSettingModel
                {
                    AlarmSettingId = item.AlarmSettingId,
                    AreaId = item.AreaId,
                    ColorString = item.Color,
                    MinPercentageGood = item.MinPercentageGood,
                    FontColorString = item.FontColor,
                    MinPercentageBad = item.MinPercentageBad,
                    CreatedBy = item.CreatedBy,
                    CreatedDate = item.CreatedDate.ToString(FormatString.DateTimeFormat),
                    LastUpdatedBy = item.LastUpdatedBy,
                    LastUpdatedDate = item.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
                };
                list.Add(rud);
            }
            AlarmSettings = list;
            IsBusy = false;
        }

        private void CloneAndBindingAlarmSetting(AlarmSettingModel alarmSettingModel)
        {
            CloneSelectedAlarmSetting = SmartReflection.CloneModel(alarmSettingModel);

            if (!CloneSelectedAlarmSetting.IsAddNew)
            {
                CloneSelectedAlarmSetting.FontColorString = alarmSettingModel.FontColorString;
                CloneSelectedAlarmSetting.ColorString = alarmSettingModel.ColorString;
            }

            CloneSelectedAlarmSetting.ShouldValidate = true;
        }
        #endregion

        #region ScrapReasonCode

        private void OnParentScrapReasonCodeClick(Object obj)
        {
            if (ParentScrapReasonTreeVisibility == Visibility.Collapsed)
            {
                ParentScrapReasonTreeVisibility = Visibility.Visible;
                ParentScrapReasonTreeButtonContent = "Hide";
            }
            else
            {
                ParentScrapReasonTreeVisibility = Visibility.Collapsed;
                ParentScrapReasonTreeButtonContent = "Show";
            }
        }

        private void OnLinkScrapReasonCodeClick(Object obj)
        {
            if (LinkScrapReasonTreeVisibility == Visibility.Collapsed)
            {
                LinkScrapReasonTreeVisibility = Visibility.Visible;
                LinkScrapReasonTreeButtonContent = "Hide";
            }
            else
            {
                LinkScrapReasonTreeVisibility = Visibility.Collapsed;
                LinkScrapReasonTreeButtonContent = "Show";
            }
        }

        private void OnAddNewScrapReasonCode()
        {
            SelectedObject = new ReasonCodeModel { IsAddNew = true, Scrap = true };
        }

        private void DoSaveScrapReasonCode(object obj)
        {
            if (!CloneSelectedScrapReasonCode.IsValid())
                return;

            var rcItem = new ReasonCodeItem
            {
                ReasonCodeId = CloneSelectedScrapReasonCode.ReasonCodeId,
                AreaId = _currentAreaModel.AreaId,
                Description = CloneSelectedScrapReasonCode.Description.TrimSafety(),
                ParentId = CloneSelectedScrapReasonCode.ParentId == 0 ? null : CloneSelectedScrapReasonCode.ParentId,
                LinkId = CloneSelectedScrapReasonCode.LinkId == 0 ? null : CloneSelectedScrapReasonCode.LinkId,
                Level = CloneSelectedScrapReasonCode.Parent != null ? (CloneSelectedScrapReasonCode.Parent.Level + 1) : 1,
                RollupDefinitionId = CloneSelectedScrapReasonCode.RollupDefinitionId == 0 ? null : CloneSelectedScrapReasonCode.RollupDefinitionId,
                Category = (ReasonCodeItem.ReasonCodeCategory)CloneSelectedScrapReasonCode.Category,
                IgnoreVisiBoxEvents = CloneSelectedScrapReasonCode.IgnoreVisiBoxEvents,
                HideChildren = CloneSelectedScrapReasonCode.HideChildren,
                FlashDelay = CloneSelectedScrapReasonCode.FlashDelay,
                Scrap = CloneSelectedScrapReasonCode.Scrap,
                DisplayInDowntimeChart = CloneSelectedScrapReasonCode.DisplayInDowntimeChart,
                IgnoreInOeeCalc = CloneSelectedScrapReasonCode.IgnoreInOeeCalc,
                IgnoreInWaitingCalc = CloneSelectedScrapReasonCode.IgnoreInWaitingCalc,
                ShopClockEvent = CloneSelectedReasonCode.ShopClockEvent
            };

            ErrorMessage = null;
            IsBusy = true;
            if (CloneSelectedScrapReasonCode.IsAddNew)
                DoAsync(AreaProvider.InsertReasonCode, InsertScrapReasonCodeCompleted, rcItem);
            else
                DoAsync(AreaProvider.UpdateReasonCode, UpdateScrapReasonCodeCompleted, rcItem);
        }

        private void DoCancelScrapReasonCode(object obj)
        {
            ErrorMessage = null;
            CloneAndBindingScrapReasonCode((ReasonCodeModel)_selectedObject);
        }

        private void DoDeleteScrapReasonCode(object obj)
        {
            ErrorMessage = null;
            if (MessageBox.Show(string.Format(FormatString.DeleteItemFormat, "scrap reason code"), TitleString.ConfirmDeleteTitle, MessageBoxButton.YesNo) == MessageBoxResult.No)
                return;

            IsBusy = true;
            DoAsync(AreaProvider.DeleteReasonCode, DeleteScrapReasonCodeCompleted, CloneSelectedScrapReasonCode.ReasonCodeId);
        }

        private void GetProductionPlanCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<ProductionPlanItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            var list = new ObservableCollection<ProductionPlanModel>();
            foreach (var item in response.Data)
            {
                var node = CreateProductionPlan(item, response.Data);
                list.Add(node);
            }
            ProductionPlans = list;
            FilteredProductionPlans = new ObservableCollection<ProductionPlanModel>(_productionPlans.Where(
                    x => x.DueDate != null && (x.DueDate.Value.Date >= StartDate && x.DueDate.Value.Date <= EndDate)).ToList());
        }

        private void GetProductionPlanReferenceCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<ProductionPlanReferenceItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            ProductionPlanReference = new ProductionPlanReferenceModel
                {
                    Cells = new List<CellModel>(),
                    Products = new List<ProductModel>(),
                    BraiderProducts = new List<BraiderProductModel>()
                };
            foreach (var cellItem in response.Data.Cells)
            {
                var cellModel = new CellModel
                    {
                        AreaId = cellItem.AreaId,
                        CellId = cellItem.CellId,
                        CellName = cellItem.CellName,
                        Description = cellItem.Description,
                        Enabled = cellItem.Enabled,
                    };
                ProductionPlanReference.Cells.Add(cellModel);
            }

            foreach (var productItem in response.Data.Products)
            {
                var product = new ProductModel
                    {
                        ProductId = productItem.ProductId,
                        Sku = productItem.Sku,
                        Description = productItem.Description,
                        Revision = productItem.Revision,
                        IsEnabled = productItem.Enabled
                    };
                ProductionPlanReference.Products.Add(product);
            }

            foreach (var braiderProductItem in response.Data.BraiderProducts)
            {
                var braiderProductModel = new BraiderProductModel
                {
                    BraiderProductId = braiderProductItem.BraiderProductId,
                    BraiderNumber = braiderProductItem.BraiderNumber,
                    BraiderType = braiderProductItem.BraiderType,
                    CarrierCount = braiderProductItem.CarrierCount,
                    ClientId = braiderProductItem.ClientId,
                    DeckCount = braiderProductItem.DeckCount,
                    FeetPerMinute = braiderProductItem.FeetPerMinute,
                    HoseCount = braiderProductItem.HoseCount,
                    HoseSize = braiderProductItem.HoseSize,
                    HoseSpec = braiderProductItem.HoseSpec,
                    OperatorId = braiderProductItem.OperatorId,
                    Split = braiderProductItem.Split,
                };
                ProductionPlanReference.BraiderProducts.Add(braiderProductModel);
            }
            DoAsync(ProductionPlanProviders.GetProductionPlans, GetProductionPlanCompleted, _currentAreaModel.AreaId);
        }

        private void UpdateProductionPlan()
        {
            foreach (var productionPlanModel in ProductionPlans)
            {
                productionPlanModel.Cell = ProductionPlanReference.Cells.FirstOrDefault(x => x.CellId == productionPlanModel.CellId);
                productionPlanModel.Product = ProductionPlanReference.Products.FirstOrDefault(x => x.ProductId == productionPlanModel.ProductId);
                productionPlanModel.BraiderProduct = ProductionPlanReference.BraiderProducts.FirstOrDefault(x => x.BraiderProductId == productionPlanModel.BraiderProductId);
            }
        }

        private void GetScrapReasonCodesCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<ReasonCodeItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            var list = new ObservableCollection<ReasonCodeModel>();
            foreach (var item in response.Data.Where(t => t.ParentId == null))
            {
                var rcm = CreateReasonCodeNode(item, response.Data);
                list.Add(rcm);
            }
            ScrapReasonCodes = list;
        }

        private void InsertScrapReasonCodeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<ReasonCodeItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedScrapReasonCode.ErrorMessage = response.Error.Description;

                CloneSelectedScrapReasonCode.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var newScrapReasonCode = CreateReasonCodeNode(response.Data, null);

            //Add to new parent
            var newParent = FindNode(response.Data.ParentId ?? 0, ScrapReasonCodes);
            if (newParent != null)
            {
                if (newParent.Children == null)
                    newParent.Children = new ObservableCollection<ReasonCodeModel>();
                newParent.Children.Add(newScrapReasonCode);
            }
            else
            {
                if (ScrapReasonCodes == null)
                    ScrapReasonCodes = new ObservableCollection<ReasonCodeModel>();
                ScrapReasonCodes.Add(newScrapReasonCode);
            }

            _selectedObject = null;
            SelectedObject = newScrapReasonCode;

            SetPendingObject();
        }

        private void UpdateScrapReasonCodeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<ReasonCodeItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedScrapReasonCode.ErrorMessage = response.Error.Description;

                CloneSelectedScrapReasonCode.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }


            var selectedScrapReasonCode = (ReasonCodeModel)_selectedObject;
            _selectedObject = null;
            var oldParentId = selectedScrapReasonCode.ParentId ?? 0;
            var newParentId = response.Data.ParentId ?? 0;
            if (oldParentId != newParentId)
            {
                //Remove from old parent
                var oldParent = FindNode(oldParentId, ScrapReasonCodes);
                if (oldParent != null && oldParent.Children != null)
                    oldParent.Children.Remove(oldParent.Children.FirstOrDefault(t => t.ReasonCodeId == selectedScrapReasonCode.ReasonCodeId));
                else if (ScrapReasonCodes != null)
                    ScrapReasonCodes.Remove(ScrapReasonCodes.FirstOrDefault(t => t.ReasonCodeId == selectedScrapReasonCode.ReasonCodeId));

                //Add to new parent
                var newParent = FindNode(newParentId, ScrapReasonCodes);
                if (newParent != null)
                {
                    if (newParent.Children == null)
                        newParent.Children = new ObservableCollection<ReasonCodeModel>();
                    newParent.Children.Add(selectedScrapReasonCode);
                }
                else
                {
                    if (ScrapReasonCodes == null)
                        ScrapReasonCodes = new ObservableCollection<ReasonCodeModel>();
                    ScrapReasonCodes.Add(selectedScrapReasonCode);
                }
            }

            selectedScrapReasonCode.Description = response.Data.Description;
            selectedScrapReasonCode.ParentId = response.Data.ParentId;
            selectedScrapReasonCode.LinkId = response.Data.LinkId;
            selectedScrapReasonCode.RollupDefinition = RollupDefinitionsSourceList.FirstOrDefault(t => t.RollupDefinitionId == response.Data.RollupDefinitionId);
            selectedScrapReasonCode.Level = response.Data.Level;
            selectedScrapReasonCode.Category = (ReasonCodeItem.ReasonCodeCategory)response.Data.Category;
            selectedScrapReasonCode.IgnoreVisiBoxEvents = response.Data.IgnoreVisiBoxEvents;
            selectedScrapReasonCode.HideChildren = response.Data.HideChildren;
            selectedScrapReasonCode.FlashDelay = response.Data.FlashDelay;
            selectedScrapReasonCode.DisplayInDowntimeChart = response.Data.DisplayInDowntimeChart;
            selectedScrapReasonCode.IgnoreInOeeCalc = response.Data.IgnoreInOeeCalc;
            selectedScrapReasonCode.IgnoreInWaitingCalc = response.Data.IgnoreInWaitingCalc;
            selectedScrapReasonCode.LastUpdatedBy = response.Data.LastUpdatedBy;
            selectedScrapReasonCode.LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat);
            selectedScrapReasonCode.ShopClockEvent = response.Data.ShopClockEvent;

            selectedScrapReasonCode.IsChange = false;
            selectedScrapReasonCode.ErrorMessage = null;
            selectedScrapReasonCode.IsCancelEnable = false;

            SelectedObject = selectedScrapReasonCode;
            SetPendingObject();
        }

        private void DeleteScrapReasonCodeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as DeleteDataResponse;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                CloneSelectedScrapReasonCode.ErrorMessage = response.Error.Description;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var parentId = ((ReasonCodeModel)SelectedObject).ParentId ?? 0;
            CloneSelectedScrapReasonCode = null;
            SelectedObject = null;

            //Remove from old parent
            var oldParent = FindNode(parentId, ScrapReasonCodes);
            if (oldParent != null && oldParent.Children != null)
                oldParent.Children.Remove(oldParent.Children.FirstOrDefault(t => t.ReasonCodeId == response.DataId));
            else if (ScrapReasonCodes != null)
                ScrapReasonCodes.Remove(ScrapReasonCodes.FirstOrDefault(t => t.ReasonCodeId == response.DataId));
        }

        private ProductionPlanModel CreateProductionPlan(ProductionPlanItem item, IList<ProductionPlanItem> list)
        {
            var cell = ProductionPlanReference.Cells.FirstOrDefault(x => x.CellId == item.CellId);
            var product = ProductionPlanReference.Products.FirstOrDefault(x => x.ProductId == item.ProductId);
            var braiderProduct = ProductionPlanReference.BraiderProducts.FirstOrDefault(x => x.BraiderProductId == item.BraiderProductId);
            var rc = new ProductionPlanModel
            {
                CellId = item.CellId,
                Cell = cell,
                ProductId = item.ProductId,
                Product = product,
                ProductionPlanId = item.ProductionPlanId,
                BraiderProductId = item.BraiderProductId,
                BraiderProduct = braiderProduct,
                WorkOrder = item.WorkOrder,
                DueDate = item.DueDate,
                Planned = item.Planned,
                Actual = item.Actual,
                SortOrder = item.SortOrder,
                Closed = item.Closed,
                Enabled = item.Enabled,
                CreatedBy = item.CreatedByUser,
                LastUpdatedBy = item.LastUpdatedByUser,
                CreatedDate = item.CreatedDate.ToString(FormatString.DateTimeFormat),
                LastUpdatedDate = item.LastUpdatedDate.ToString(FormatString.DateTimeFormat)
            };

            return rc;
        }

        private void CreateScrapReasonCodesAsSource(int scrapScrapReasonCodeId)
        {
            if (ScrapReasonCodes == null)
                return;

            ScrapReasonCodesSourceList = new ObservableCollection<ReasonCodeModel>() { new ReasonCodeModel { ReasonCodeId = 0, Description = "- No Parent -", Children = new ObservableCollection<ReasonCodeModel>(), } };
            foreach (var rc in ScrapReasonCodes)
            {
                if (rc.ReasonCodeId == scrapScrapReasonCodeId)
                    continue;

                ScrapReasonCodesSourceList[0].Children.Add(CreateScrapReasonCodeNodeForSource(scrapScrapReasonCodeId, rc));
            }
        }

        private ReasonCodeModel CreateScrapReasonCodeNodeForSource(int scrapScrapReasonCodeId, ReasonCodeModel rc)
        {
            var rcm = new ReasonCodeModel
            {
                ReasonCodeId = rc.ReasonCodeId,
                Description = rc.Description,
                Level = rc.Level,
                Children = new ObservableCollection<ReasonCodeModel>()
            };

            if (rc.Children != null)
                foreach (var child in rc.Children)
                {
                    if (child.ReasonCodeId == scrapScrapReasonCodeId)
                        continue;

                    rcm.Children.Add(CreateScrapReasonCodeNodeForSource(scrapScrapReasonCodeId, child));
                }
            return rcm;
        }

        private void CloneAndBindingScrapReasonCode(ReasonCodeModel value)
        {
            CreateScrapReasonCodesAsSource(value.ReasonCodeId);
            CloneSelectedScrapReasonCode = SmartReflection.CloneModel(value);
            CloneSelectedScrapReasonCode.RollupDefinition = RollupDefinitionsSourceList != null ?
                RollupDefinitionsSourceList.FirstOrDefault(t => t.RollupDefinitionId == CloneSelectedScrapReasonCode.RollupDefinitionId) : null;
            CloneSelectedScrapReasonCode.Parent = FindNode(CloneSelectedScrapReasonCode.ParentId ?? 0, ScrapReasonCodesSourceList);
            CloneSelectedScrapReasonCode.Link = FindNode(CloneSelectedScrapReasonCode.LinkId ?? 0, ScrapReasonCodesSourceList);
            CloneSelectedScrapReasonCode.ShouldValidate = true;
        }

        #endregion

        #region Production Plan
        private void DoDeleteProductionPlanCommand(object obj)
        {
            ErrorMessage = null;
            if (MessageBox.Show(string.Format(FormatString.DeleteItemFormat, "plan production"), TitleString.ConfirmDeleteTitle, MessageBoxButton.YesNo) == MessageBoxResult.No)
                return;

            IsBusy = true;
            DoAsync(ProductionPlanProviders.DeleteProductionPlan, DeleteProductionPlanCompleted, CloneSelectedProductionPlan.ProductionPlanId);
        }

        private void DoCancelProductionPlanCommand(object obj)
        {
            ErrorMessage = null;
            CloneAndBindingProductionPlan((ProductionPlanModel)_selectedObject);
        }

        private void CloneAndBindingProductionPlan(ProductionPlanModel value)
        {
            CloneSelectedProductionPlan = SmartReflection.CloneModel(value);
            CloneSelectedProductionPlan.ShouldValidate = true;
        }

        private void DoSaveProductionPlanCommand(object obj)
        {
            if (!CloneSelectedProductionPlan.IsValid())
                return;

            var productionPlanItem = new ProductionPlanItem
            {
                CellId = CloneSelectedProductionPlan.CellId,
                ProductId = CloneSelectedProductionPlan.ProductId,
                ProductionPlanId = CloneSelectedProductionPlan.ProductionPlanId,
                WorkOrder = CloneSelectedProductionPlan.WorkOrder,
                DueDate = CloneSelectedProductionPlan.DueDate.Value,
                Planned = CloneSelectedProductionPlan.Planned,
                Actual = CloneSelectedProductionPlan.Actual,
                SortOrder = CloneSelectedProductionPlan.SortOrder,
                Closed = CloneSelectedProductionPlan.Closed,
                Enabled = CloneSelectedProductionPlan.Enabled,
            };

            ErrorMessage = null;
            IsBusy = true;
            if (CloneSelectedProductionPlan.IsAddNew)
                DoAsync(ProductionPlanProviders.InsertProductionPlan, InsertProductionPlanCompleted, productionPlanItem);
            else
                DoAsync(ProductionPlanProviders.UpdateProductionPlan, UpdateProductionPlanCompleted, productionPlanItem);
        }

        private void UpdateProductionPlanCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<ProductionPlanItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedProductionPlan.ErrorMessage = response.Error.Description;

                CloneSelectedProductionPlan.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            var productionPlanModel = (ProductionPlanModel)_selectedObject;

            productionPlanModel.Cell = ProductionPlanReference.Cells.FirstOrDefault(x => x.CellId == response.Data.CellId);
            productionPlanModel.Product = ProductionPlanReference.Products.FirstOrDefault(x => x.ProductId == response.Data.ProductId);
            productionPlanModel.BraiderProduct = ProductionPlanReference.BraiderProducts.FirstOrDefault(x => x.BraiderProductId == response.Data.BraiderProductId);
            productionPlanModel.WorkOrder = response.Data.WorkOrder;
            productionPlanModel.DueDate = response.Data.DueDate;
            productionPlanModel.Planned = response.Data.Planned;
            productionPlanModel.Actual = response.Data.Actual;
            productionPlanModel.SortOrder = response.Data.SortOrder;
            productionPlanModel.Closed = response.Data.Closed;
            productionPlanModel.Enabled = response.Data.Enabled;
            productionPlanModel.LastUpdatedBy = response.Data.LastUpdatedByUser;
            productionPlanModel.LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat);

            productionPlanModel.IsChange = false;
            productionPlanModel.ErrorMessage = null;
            productionPlanModel.IsCancelEnable = false;
            CloneAndBindingProductionPlan(productionPlanModel);

            SetPendingObject();
        }

        private void InsertProductionPlanCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<ProductionPlanItem>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    CloneSelectedProductionPlan.ErrorMessage = response.Error.Description;

                CloneSelectedProductionPlan.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }
            var productionPlanItem = new ProductionPlanModel
            {
                Cell = ProductionPlanReference.Cells.FirstOrDefault(x => x.CellId == response.Data.CellId),
                Product = ProductionPlanReference.Products.FirstOrDefault(x => x.ProductId == response.Data.ProductId),
                BraiderProduct = ProductionPlanReference.BraiderProducts.FirstOrDefault(x => x.BraiderProductId == response.Data.BraiderProductId),
                ProductionPlanId = response.Data.ProductionPlanId,
                WorkOrder = CloneSelectedProductionPlan.WorkOrder,
                DueDate = CloneSelectedProductionPlan.DueDate,
                Planned = CloneSelectedProductionPlan.Planned,
                Actual = CloneSelectedProductionPlan.Actual,
                SortOrder = CloneSelectedProductionPlan.SortOrder,
                Closed = CloneSelectedProductionPlan.Closed,
                Enabled = CloneSelectedProductionPlan.Enabled,
                CreatedBy = response.Data.CreatedByUser,
                CreatedDate = response.Data.CreatedDate.ToString(FormatString.DateTimeFormat),
                LastUpdatedBy = response.Data.LastUpdatedByUser,
                LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
            };

            ProductionPlans.Add(productionPlanItem);
            FilteredProductionPlans = new ObservableCollection<ProductionPlanModel>(_productionPlans.Where(
                    x => x.DueDate != null && (x.DueDate.Value.Date >= StartDate && x.DueDate.Value.Date <= EndDate)).ToList());
            _selectedObject = null;
            SelectedObject = productionPlanItem;

            SetPendingObject();
        }

        private void DeleteProductionPlanCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as DeleteDataResponse;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                {
                    CloneSelectedAreaShift.ErrorMessage = response.Error.Description;
                }
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                NavigateBack();
                return;
            }

            CloneSelectedProductionPlan = null;
            SelectedObject = null;

            var item = ProductionPlans.FirstOrDefault(t => t.ProductionPlanId == response.DataId);
            if (item != null)
                ProductionPlans.Remove(item);
            FilteredProductionPlans = new ObservableCollection<ProductionPlanModel>(_productionPlans.Where(
                    x => x.DueDate != null && (x.DueDate.Value.Date >= StartDate && x.DueDate.Value.Date <= EndDate)).ToList());
        }

        private void ImportProductionPlanMenuClick()
        {
            using (var openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = Resources.ExcelFileFilter;
                openFileDialog.Title = Resources.SelectProductionPlan;
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        var importers = new ExcelReaders();
                        var productionPlans = importers.GetProductionPlans(openFileDialog.FileName);
                        MergeProductionPlans(productionPlans);
                    }
                    catch (Exception ex)
                    {
                        System.Windows.Forms.MessageBox.Show(ex.Message);
                    }

                }
            }
        }

        private void MergeProductionPlans(IExcelData products)
        {
            var productData = products as ProductionPlanData;
            if (productData != null && productData.Items != null)
            {
                var items = productData.Items.Select((item, index) => new ProductionPlanItem
                {
                    Sku = item.Sku,
                    CellName = item.CellName,
                    WorkOrder = item.WorkOrder,
                    Enabled = item.Enabled,
                    DueDate = item.DueDate,
                    Planned = item.Planned,
                    Actual = item.Actual,
                    SortOrder = index,
                }).ToList();
                IsBusy = true;
                DoAsync(ProductionPlanProviders.ImportProductionPlan, ImportProductionPlanCompleted, items);
            }
        }

        private void ImportProductionPlanCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<IList<ProductionPlanItem>>;
            IsBusy = false;
            if (response == null || !response.Success)
            {
                if (response != null)
                {
                    MessageBox.Show(response.Error.Description);
                }
                return;
            }
            if (IsClosing)
            {
                NavigateBack();
                return;
            }
            RefreshPage();
        }

        private void RefreshPage()
        {
            IsBusy = true;
            DoAsync(ProductionPlanProviders.GetProductionPlanReference, GetProductionPlanReferenceCompleted, _currentAreaModel.AreaId);
        }

        #endregion

        #region Scheduled Downtime

        private void GetScheduledDowntimeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<ScheduledDowntimeItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                {
                    ErrorMessage = response.Error.Description;
                }
                return;
            }


            var list = new ObservableCollection<Appointment>();
            foreach (var item in response.Data)
            {
                list.Add(new Appointment
                {
                    Id = item.ScheduleId.ToString(),
                    Categories = item.AreaId.ToString(),
                    Subject = item.Subject,
                    Start = item.StartTime,
                    End = item.EndTime,
                    OwningResourceId = "defaultUser",
                    OwningCalendarId = "defaultCalendar",
                    Description = item.ReasonCodeId.ToString(),
                    RecurrenceVersion = item.ScheduleRepeatId.GetValueOrDefault(),
                    StartTimeZoneId = item.CreatedBy,
                    OriginalOccurrenceStart = item.CreatedDate,
                    EndTimeZoneId = item.LastUpdatedBy,
                    OriginalOccurrenceEnd = item.LastUpdatedDate,
                    ReminderEnabled = false
                });
            }

            ScheduledDowntimes = list;

            var request = new GetDataRequest
            {
                Identity = UserTransportToken.UserIdentity,
                Id = 1,
            };
            var client = new VNetVisiSuiteContractClient();
            var obj = client.GetScheduledRepeat(request).Data;
            var listCombo = new ObservableCollection<ScheduleRepeatModel>();
            foreach (var item in obj)
            {
                listCombo.Add(new ScheduleRepeatModel
                {
                    IsEveryMonday = item.IsEveryMonday,
                    ScheduleRepeatID = item.ScheduleRepeatID,
                });
            }
            ScheduleRepeat = listCombo;

            //var request = new GetDataRequest
            //{
            //    Identity = UserTransportToken.UserIdentity,
            //    Id = 13,
            //};
            //var client = new VNetVisiSuiteContractClient();
            //var obj = client.GetScheduledDowntimes(request);

            //var listCombo = new ObservableCollection<ReasonCodeModel>();
            //foreach (var item in response.Data)
            //{
            //    listCombo.Add(new ReasonCodeModel
            //    {
            //        ReasonCodeId = item.ReasonCodeId,
            //        Description = item.Description,
            //    });
            //}
            //ReasonCodesSourceComboList = listCombo;
        }


        public void DoSaveSchedule(object obj)
        {
            if (!CloneSelectedSchedule.IsValid())
                return;

            var scItem = new ScheduledDowntimeItem
                             {
                                 AreaId = _currentAreaModel.AreaId,
                                 Subject = CloneSelectedSchedule.Subject,
                                 ReasonCodeId = CloneSelectedSchedule.ReasonCodeId,
                                 StartTime = CloneSelectedSchedule.StartTime,
                                 EndTime = CloneSelectedSchedule.EndTime,
                                 ScheduleRepeatId = CloneSelectedSchedule.ScheduleRepeatId,
                                 ScheduleId = CloneSelectedSchedule.ScheduleId
                             };
            ErrorMessage = null;

            //var newScheduledDowntime = new ScheduleModel()
            //{
            //    AreaId = obj..AreaId,
            //    EndTime = response.Data.EndTime,
            //    StartTime = response.Data.StartTime,
            //    ScheduleRepeatId = response.Data.ScheduleRepeatId,
            //    Subject = response.Data.Subject,
            //    ScheduleId = response.Data.ScheduleId,
            //    CreatedBy = response.Data.CreatedBy,
            //    CreatedDate = response.Data.CreatedDate.ToString(FormatString.DateTimeFormat),
            //    LastUpdatedBy = response.Data.LastUpdatedBy,
            //    LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
            //};

            if (CloneSelectedSchedule.IsAddNew)
                DoAsync(AreaProvider.InsertScheduleDowntime, InsertScheduleDowntimeCompleted, scItem);
            //Schedules.Add(obj);

                //InsertScheduleDowntimeCompleted();
            else
                DoAsync(AreaProvider.UpdateScheduledDowntime, UpdateScheduleDowntimeCompleted, scItem);
        }


        private void DoDeleteSchedule(object obj)
        {
            ErrorMessage = null;
            if (MessageBox.Show(string.Format(FormatString.DeleteItemFormat, "schedule"), TitleString.ConfirmDeleteTitle, MessageBoxButton.YesNo) == MessageBoxResult.No)
                return;

            IsBusy = true;
            DoAsync(AreaProvider.DeleteScheduleDowntime, DeleteScheduleCompleted, CloneSelectedSchedule.ScheduleId);
        }

        private void DoCancelSchedule(object obj)
        {
            ErrorMessage = null;
            CloneAndBindingSchedule((ScheduleModel)_selectedObject);
        }


        private void DeleteScheduleCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as DeleteDataResponse;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                {
                    CloneSelectedSchedule.ErrorMessage = response.Error.Description;
                }
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }

            CloneSelectedSchedule = null;
            SelectedObject = null;

            var item = ScheduledDowntimes.FirstOrDefault(t => t.Id == response.DataId.ToString());
            if (item != null)
                ScheduledDowntimes.Remove(item);
            IsBusy = false;
        }


        private void UpdateScheduleDowntimeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<ScheduledDowntimeItem>;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                    CloneSelectedSchedule.ErrorMessage = response.Error.Description;

                CloneSelectedSchedule.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }


            var scheduleModel = (ScheduleModel)_selectedObject;
            scheduleModel.AreaId = response.Data.AreaId;
            scheduleModel.EndTime = response.Data.EndTime;
            scheduleModel.StartTime = response.Data.StartTime;
            scheduleModel.ScheduleRepeatId = response.Data.ScheduleRepeatId;
            scheduleModel.Subject = response.Data.Subject;

            scheduleModel.LastUpdatedBy = response.Data.LastUpdatedBy;
            scheduleModel.LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat);

            scheduleModel.IsChange = false;
            ErrorMessage = null;
            scheduleModel.IsCancelEnable = false;


            //var appointment = new Appointment()
            //{
            //    Id = response.Data.ScheduleId.ToString(),
            //    Categories = response.Data.AreaId.ToString(),
            //    Subject = response.Data.Subject,
            //    Start = response.Data.StartTime,
            //    End = response.Data.EndTime,
            //    OwningResourceId = "defaultUser",
            //    OwningCalendarId = "defaultCalendar",
            //    Description = response.Data.ReasonCodeId.ToString(),
            //    RecurrenceVersion = response.Data.ScheduleRepeatId.GetValueOrDefault(),
            //    StartTimeZoneId = response.Data.CreatedBy,
            //    OriginalOccurrenceStart = response.Data.CreatedDate,
            //    EndTimeZoneId = response.Data.LastUpdatedBy,
            //    OriginalOccurrenceEnd = response.Data.LastUpdatedDate,
            //    ReminderEnabled = false,
            //};

            foreach (var t in ScheduledDowntimes)
            {
                if (t.Id == response.Data.ScheduleId.ToString())
                {
                    t.Id = response.Data.ScheduleId.ToString();
                    t.Categories = response.Data.AreaId.ToString();
                    t.Subject = response.Data.Subject;
                    t.Start = response.Data.StartTime;
                    t.End = response.Data.EndTime;
                    t.OwningResourceId = "defaultUser";
                    t.OwningCalendarId = "defaultCalendar";
                    t.Description = response.Data.ReasonCodeId.ToString();
                    t.RecurrenceVersion = response.Data.ScheduleRepeatId.GetValueOrDefault();
                    t.StartTimeZoneId = response.Data.CreatedBy;
                    t.OriginalOccurrenceStart = response.Data.CreatedDate;
                    t.EndTimeZoneId = response.Data.LastUpdatedBy;
                    t.OriginalOccurrenceEnd = response.Data.LastUpdatedDate;
                    t.ReminderEnabled = false;
                    break;
                }
            }

            CloneAndBindingSchedule(scheduleModel);

            SetPendingObject();
            IsBusy = false;
        }


        private void InsertScheduleDowntimeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SaveDataResponse<ScheduledDowntimeItem>;

            if (response == null || !response.Success)
            {
                IsBusy = false;
                if (response != null)
                    CloneSelectedSchedule.ErrorMessage = response.Error.Description;

                CloneSelectedSchedule.IsCancelEnable = false;
                _pendingObject = null;
                IsClosing = false;
                return;
            }

            if (IsClosing)
            {
                IsBusy = false;
                NavigateBack();
                return;
            }

            var newScheduledDowntime = new Appointment
            {
                Id = response.Data.ScheduleId.ToString(),
                Categories = response.Data.AreaId.ToString(),
                Subject = response.Data.Subject,
                Start = response.Data.StartTime,
                End = response.Data.EndTime,
                OwningResourceId = "defaultUser",
                OwningCalendarId = "defaultCalendar",
                Description = response.Data.ReasonCodeId.ToString(),
                RecurrenceVersion = response.Data.ScheduleRepeatId.GetValueOrDefault(),
                StartTimeZoneId = response.Data.CreatedBy,
                OriginalOccurrenceStart = response.Data.CreatedDate,
                EndTimeZoneId = response.Data.LastUpdatedBy,
                OriginalOccurrenceEnd = response.Data.LastUpdatedDate,
                ReminderEnabled = false
            };

            ScheduledDowntimes.Add(newScheduledDowntime);

            var newScheduleDowntime = new ScheduleModel()
            {
                ScheduleId = response.Data.ScheduleId,
                AreaId = response.Data.AreaId,
                EndTime = response.Data.EndTime,
                StartTime = response.Data.StartTime,
                ScheduleRepeatId = response.Data.ScheduleRepeatId,
                Subject = response.Data.Subject,
                ReasonCodeId = response.Data.ReasonCodeId,
                CreatedBy = response.Data.CreatedBy,
                CreatedDate = response.Data.CreatedDate.ToString(FormatString.DateTimeFormat),
                LastUpdatedBy = response.Data.LastUpdatedBy,
                LastUpdatedDate = response.Data.LastUpdatedDate.ToString(FormatString.DateTimeFormat),
            };

            _selectedObject = null;
            SelectedObject = newScheduleDowntime;

            SetPendingObject();
            IsBusy = false;
        }


        public void CloneAndBindingSchedule(ScheduleModel scheduleModel)
        {
            CloneSelectedSchedule = SmartReflection.CloneModel(scheduleModel);

            if (CloneSelectedSchedule.IsAddNew)
            {
                CloneSelectedSchedule.StartTime = DateTime.Now;
                CloneSelectedSchedule.EndTime = DateTime.Now;
            }

            CloneSelectedSchedule.ShouldValidate = true;
        }

        #endregion

        #region Helper methods

        private void OnAddNewItemCallback()
        {
            var header = _selectedTabItem.Header.ToString();
            if (header == ShiftTabHeader)
            {
                OnAddNewAreaShift();
            }
            else if (header == ReasonCodeTabHeader)
            {
                OnAddNewReasonCode();
            }
            else if (header == RollupDefTabHeader)
            {
                OnAddNewRollupDef();
            }
            else if (header == AlarmSettingTabHeader)
            {
                OnAddNewAlarmSetting();
            }
            else if (header == ScrapReasonCodeTabHeader)
            {
                OnAddNewScrapReasonCode();
            }
            else if (header == ApplicationTabHeader)
            {
                OnAddNewApplication();
            }
            else if (header == ProductionPlanTabHeader)
            {
                OnAddNewProductionPlan();
            }
            else if (header == ScheduledDowntimeTabHeader)
            {
                OnAddNewScheduledDowntime();
            }
        }

        private void OnMoveDownCallback()
        {
            var header = _selectedTabItem.Header.ToString();
            if (header == RollupDefTabHeader)
            {
                OnMoveDownRollupDef();
            }
            else if (header == ApplicationTabHeader)
            {
                OnMoveDownApplication();
            }
        }

        private void OnMoveUpCallback()
        {
            var header = _selectedTabItem.Header.ToString();
            if (header == RollupDefTabHeader)
            {
                OnMoveUpRollupDef();
            }
            else if (header == ApplicationTabHeader)
            {
                OnMoveUpApplication();
            }
        }

        private void OnExit()
        {
            if (_selectedObject != null)
            {
                IsClosing = true;
                var currentType = _selectedObject.GetType();
                if (currentType == typeof(AreaShiftModel) && IsAreaShiftPendingChange(null)
                    || currentType == typeof(LaunchApplicationModel) && IsApplicationPendingChange(null)
                    || (currentType == typeof(ReasonCodeModel) && !((ReasonCodeModel)_selectedObject).Scrap && IsReasonCodePendingChange(null))
                    || (currentType == typeof(ReasonCodeModel) && ((ReasonCodeModel)_selectedObject).Scrap && IsScrapReasonCodePendingChange(null))
                    || currentType == typeof(RollupDefinitionModel) && IsRollupDefPendingChange(null)
                    )
                {
                    return;
                }
            }

            NavigateBack();
        }

        private void NavigateBack()
        {
            NavigationManager.NavigateTo(new PlantView(), null);
        }

        private void SetPendingObject()
        {
            if (_pendingObject != null)
            {
                _cloneSelectedAreaShift = null;
                _cloneSelectedLaunchApplication = null;
                _cloneSelectedReasonCode = null;
                _cloneSelectedScrapReasonCode = null;
                _cloneSelectedRollupDefinition = null;
                _cloneSelectedProductionPlan = null;
                _cloneSelectedAlarmSetting = null;

                SelectedObject = _pendingObject;
                _pendingObject = null;
            }
        }

        public bool IsAreaShiftPendingChange(object value)
        {
            if (_cloneSelectedAreaShift != null && _cloneSelectedAreaShift.HasChange())
            {
                switch (ConfirmDialog.Show())
                {
                    case SaveChangesDialogResult.Discard:
                        return false;
                    case SaveChangesDialogResult.Save:
                        _pendingObject = value;
                        DoSaveAreaShift(null);
                        return true;
                    case SaveChangesDialogResult.Resume:
                        IsClosing = false;
                        _pendingObject = null;
                        return true;
                }
            }
            return false;
        }

        public bool IsApplicationPendingChange(object value)
        {
            if (_cloneSelectedLaunchApplication != null && _cloneSelectedLaunchApplication.HasChange())
            {
                switch (ConfirmDialog.Show())
                {
                    case SaveChangesDialogResult.Discard:
                        return false;
                    case SaveChangesDialogResult.Save:
                        _pendingObject = value;
                        DoSaveLaunchApplication(null);
                        return true;
                    case SaveChangesDialogResult.Resume:
                        IsClosing = false;
                        _pendingObject = null;
                        return true;
                }
            }
            return false;
        }

        public bool IsReasonCodePendingChange(object value)
        {
            if (_cloneSelectedReasonCode != null && _cloneSelectedReasonCode.HasChange())
            {
                switch (ConfirmDialog.Show())
                {
                    case SaveChangesDialogResult.Discard:
                        return false;
                    case SaveChangesDialogResult.Save:
                        _pendingObject = value;
                        DoSaveReasonCode(null);
                        return true;
                    case SaveChangesDialogResult.Resume:
                        IsClosing = false;
                        _pendingObject = null;
                        return true;
                }
            }
            return false;
        }

        public bool IsRollupDefPendingChange(object value)
        {
            if (_cloneSelectedRollupDefinition != null && _cloneSelectedRollupDefinition.HasChange())
            {
                switch (ConfirmDialog.Show())
                {
                    case SaveChangesDialogResult.Discard:
                        return false;
                    case SaveChangesDialogResult.Save:
                        _pendingObject = value;
                        DoSaveRollupDef(null);
                        return true;
                    case SaveChangesDialogResult.Resume:
                        IsClosing = false;
                        _pendingObject = null;
                        return true;
                }
            }
            return false;
        }

        public bool IsProductionPlanPendingChange(object value)
        {
            if (_cloneSelectedProductionPlan != null && _cloneSelectedProductionPlan.HasChange())
            {
                switch (ConfirmDialog.Show())
                {
                    case SaveChangesDialogResult.Discard:
                        return false;
                    case SaveChangesDialogResult.Save:
                        _pendingObject = value;
                        DoSaveProductionPlanCommand(null);
                        return true;
                    case SaveChangesDialogResult.Resume:
                        IsClosing = false;
                        _pendingObject = null;
                        return true;
                }
            }
            return false;
        }

        public bool IsScrapReasonCodePendingChange(object value)
        {
            if (_cloneSelectedScrapReasonCode != null && _cloneSelectedScrapReasonCode.HasChange())
            {
                switch (ConfirmDialog.Show())
                {
                    case SaveChangesDialogResult.Discard:
                        return false;
                    case SaveChangesDialogResult.Save:
                        _pendingObject = value;
                        DoSaveScrapReasonCode(null);
                        return true;
                    case SaveChangesDialogResult.Resume:
                        IsClosing = false;
                        _pendingObject = null;
                        return true;
                }
            }
            return false;
        }

        private bool IsAlarmSettingPendingChange(object value)
        {
            if (_cloneSelectedAlarmSetting != null && _cloneSelectedAlarmSetting.HasChange())
            {
                switch (ConfirmDialog.Show())
                {
                    case SaveChangesDialogResult.Discard:
                        return false;
                    case SaveChangesDialogResult.Save:
                        _pendingObject = value;
                        DoSaveAlarmSetting(null);
                        return true;
                    case SaveChangesDialogResult.Resume:
                        IsClosing = false;
                        _pendingObject = null;
                        return true;
                }
            }
            return false;
        }


        private bool IsScheduledDowntimePendingChange(object value)
        {
            if (_cloneSelectedSchedule != null && _cloneSelectedSchedule.HasChange())
            {
                switch (ConfirmDialog.Show())
                {
                    case SaveChangesDialogResult.Discard:
                        return false;
                    case SaveChangesDialogResult.Save:
                        _pendingObject = value;
                        DoSaveSchedule(null);
                        return true;
                    case SaveChangesDialogResult.Resume:
                        IsClosing = false;
                        _pendingObject = null;
                        return true;
                }
            }
            return false;
        }


        #endregion

        #endregion

        #region Navigation Framwork
        public override void OnNavigate(object obj)
        {
            _currentAreaModel = (AreaModel)obj;

            PageTitle = string.Format(TitleString.AreaDetailsAdminTitle, _currentAreaModel.AreaName);
            ErrorMessage = null;
            SelectedTabItem = SelectedTabItem;
        }

        public override void OnLeave()
        {
        }
        #endregion
    }
}
